You are viewing a plain text version of this content. The canonical link for it is here.
Posted to users@camel.apache.org by Jose Espinosa <jo...@revinate.com> on 2013/08/16 20:10:42 UTC

Authenticating websockets endpoints.

Hey all,

I am using websockets to start on of my routes, now I am looking at
adding security to my websockets end points.

I took a look at camel security as described here
http://camel.apache.org/camel-security.html and it works as
advertised, but now I cann't find how to make my websocket client to
authenticate.

Any pointers on how to make my websocket client to authenticate with camel?

Thank you very much,
Jose

Re: Authenticating websockets endpoints.

Posted by Jose Espinosa <jo...@revinate.com>.
I want to share my solution.  I did not find a way to authenticate the
"Upgrade" message and the websocket messages do not send headers.  So
I add the basic authentication to my message payload.  The code is:

 *********************

package com.revinate.sifter.auth;

import org.apache.camel.Exchange;
import org.apache.camel.Message;
import org.apache.camel.Processor;
import org.codehaus.jackson.map.ObjectMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.AccessDeniedException;
import org.springframework.security.authentication.BadCredentialsException;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.crypto.codec.Base64;
import org.springframework.stereotype.Component;

import javax.security.auth.Subject;
import java.io.IOException;
import java.util.Map;

@Component
public class WebsocketAuthentication implements Processor {
    @Autowired
    private UserDetailsService userDetailsService;

    @Override
    public void process(Exchange exchange) throws IOException {
        Message in = exchange.getIn();
        String body = in.getBody(String.class);
        Map<?, ?> payload = new ObjectMapper().readValue(body, Map.class);
        if (payload.containsKey("basic")) {
            String s = (String) payload.get("basic");
            String[] t = extractAndDecodeHeader(s);

            UserDetails userDetails =
userDetailsService.loadUserByUsername(t[0]);
            if (userDetails.isAccountNonExpired() &&
                userDetails.isAccountNonLocked() &&
                userDetails.isCredentialsNonExpired() &&
                userDetails.isEnabled() &&
                t[1].equals(userDetails.getPassword())) {
                    Authentication userPrincipal = new
UsernamePasswordAuthenticationToken(userDetails.getUsername(),
                      userDetails.getPassword(), userDetails.getAuthorities());
                    Subject subject = new Subject();
                    subject.getPrincipals().add(userPrincipal);

                    in.setHeader(Exchange.AUTHENTICATION, subject);
                    in.setBody(payload.get("data"));
            } else {
                throw new AccessDeniedException("User do not have
access to this resource.");
            }
        }

    }

    private String[] extractAndDecodeHeader(String header) throws IOException {

        byte[] base64Token = header.substring(6).getBytes("UTF-8");
        byte[] decoded;
        try {
            decoded = Base64.decode(base64Token);
        } catch (IllegalArgumentException e) {
            throw new BadCredentialsException("Failed to decode basic
authentication token");
        }

        String token = new String(decoded);

        int delim = token.indexOf(":");

        if (delim == -1) {
            throw new BadCredentialsException("Invalid basic
authentication token");
        }
        return new String[] {token.substring(0, delim),
token.substring(delim + 1)};
    }

}


On Sat, Aug 17, 2013 at 7:56 AM, Christian Posta
<ch...@gmail.com> wrote:
> Spring Security does, iirc but might have a look at the underlying
> websocket connector and its configs. Its implemented with Jetty.
>
>
> On Fri, Aug 16, 2013 at 3:01 PM, Jose Espinosa <jo...@revinate.com> wrote:
>
>> Hey Christian,
>>
>> Thanks for the response, I have already have look and the sources you
>> point and they let me make some progress as I am using spring and I am
>> already using it for securing my http requests.
>>
>> If I understand correctly I need to add the authentication information
>> in the payload of my socket and I need to set that information to the
>> Exchange.AUTHENTICATION header right?  I already hack a way to create
>> a mock authentication that let me access the websockets.
>>
>> I want to use Basic authentication but role my own security is always
>> a bad idea.  Do you know if spring provide some helper classes for
>> Basic Authentication?
>>
>> Thank you very much,
>> Jose
>>
>> On Fri, Aug 16, 2013 at 1:05 PM, Christian Posta
>> <ch...@gmail.com> wrote:
>> > Jose,
>> > Depends on which security mechanism you use. For example, for
>> > spring-security, take a look here:
>> >
>> > http://camel.apache.org/spring-security.html
>> >
>> > You can set up the infrastructure for Spring Security to intercept and
>> > validate the authentication, but the Authentication object being on the
>> > exchange is your responsibility. You can add a processor that reads the
>> > websocket payload and extracts the un/pw from there. You can also set up
>> > the websocket connection to go over SSL to avoid sending plaintext.
>> >
>> > http://camel.apache.org/websocket.html
>> >
>> >
>> >
>> >
>> > On Fri, Aug 16, 2013 at 11:10 AM, Jose Espinosa <jo...@revinate.com>
>> wrote:
>> >
>> >> Hey all,
>> >>
>> >> I am using websockets to start on of my routes, now I am looking at
>> >> adding security to my websockets end points.
>> >>
>> >> I took a look at camel security as described here
>> >> http://camel.apache.org/camel-security.html and it works as
>> >> advertised, but now I cann't find how to make my websocket client to
>> >> authenticate.
>> >>
>> >> Any pointers on how to make my websocket client to authenticate with
>> camel?
>> >>
>> >> Thank you very much,
>> >> Jose
>> >>
>> >
>> >
>> >
>> > --
>> > *Christian Posta*
>> > http://www.christianposta.com/blog
>> > twitter: @christianposta
>>
>
>
>
> --
> *Christian Posta*
> http://www.christianposta.com/blog
> twitter: @christianposta

Re: Authenticating websockets endpoints.

Posted by Christian Posta <ch...@gmail.com>.
Spring Security does, iirc but might have a look at the underlying
websocket connector and its configs. Its implemented with Jetty.


On Fri, Aug 16, 2013 at 3:01 PM, Jose Espinosa <jo...@revinate.com> wrote:

> Hey Christian,
>
> Thanks for the response, I have already have look and the sources you
> point and they let me make some progress as I am using spring and I am
> already using it for securing my http requests.
>
> If I understand correctly I need to add the authentication information
> in the payload of my socket and I need to set that information to the
> Exchange.AUTHENTICATION header right?  I already hack a way to create
> a mock authentication that let me access the websockets.
>
> I want to use Basic authentication but role my own security is always
> a bad idea.  Do you know if spring provide some helper classes for
> Basic Authentication?
>
> Thank you very much,
> Jose
>
> On Fri, Aug 16, 2013 at 1:05 PM, Christian Posta
> <ch...@gmail.com> wrote:
> > Jose,
> > Depends on which security mechanism you use. For example, for
> > spring-security, take a look here:
> >
> > http://camel.apache.org/spring-security.html
> >
> > You can set up the infrastructure for Spring Security to intercept and
> > validate the authentication, but the Authentication object being on the
> > exchange is your responsibility. You can add a processor that reads the
> > websocket payload and extracts the un/pw from there. You can also set up
> > the websocket connection to go over SSL to avoid sending plaintext.
> >
> > http://camel.apache.org/websocket.html
> >
> >
> >
> >
> > On Fri, Aug 16, 2013 at 11:10 AM, Jose Espinosa <jo...@revinate.com>
> wrote:
> >
> >> Hey all,
> >>
> >> I am using websockets to start on of my routes, now I am looking at
> >> adding security to my websockets end points.
> >>
> >> I took a look at camel security as described here
> >> http://camel.apache.org/camel-security.html and it works as
> >> advertised, but now I cann't find how to make my websocket client to
> >> authenticate.
> >>
> >> Any pointers on how to make my websocket client to authenticate with
> camel?
> >>
> >> Thank you very much,
> >> Jose
> >>
> >
> >
> >
> > --
> > *Christian Posta*
> > http://www.christianposta.com/blog
> > twitter: @christianposta
>



-- 
*Christian Posta*
http://www.christianposta.com/blog
twitter: @christianposta

Re: Authenticating websockets endpoints.

Posted by Jose Espinosa <jo...@revinate.com>.
Hey Christian,

Thanks for the response, I have already have look and the sources you
point and they let me make some progress as I am using spring and I am
already using it for securing my http requests.

If I understand correctly I need to add the authentication information
in the payload of my socket and I need to set that information to the
Exchange.AUTHENTICATION header right?  I already hack a way to create
a mock authentication that let me access the websockets.

I want to use Basic authentication but role my own security is always
a bad idea.  Do you know if spring provide some helper classes for
Basic Authentication?

Thank you very much,
Jose

On Fri, Aug 16, 2013 at 1:05 PM, Christian Posta
<ch...@gmail.com> wrote:
> Jose,
> Depends on which security mechanism you use. For example, for
> spring-security, take a look here:
>
> http://camel.apache.org/spring-security.html
>
> You can set up the infrastructure for Spring Security to intercept and
> validate the authentication, but the Authentication object being on the
> exchange is your responsibility. You can add a processor that reads the
> websocket payload and extracts the un/pw from there. You can also set up
> the websocket connection to go over SSL to avoid sending plaintext.
>
> http://camel.apache.org/websocket.html
>
>
>
>
> On Fri, Aug 16, 2013 at 11:10 AM, Jose Espinosa <jo...@revinate.com> wrote:
>
>> Hey all,
>>
>> I am using websockets to start on of my routes, now I am looking at
>> adding security to my websockets end points.
>>
>> I took a look at camel security as described here
>> http://camel.apache.org/camel-security.html and it works as
>> advertised, but now I cann't find how to make my websocket client to
>> authenticate.
>>
>> Any pointers on how to make my websocket client to authenticate with camel?
>>
>> Thank you very much,
>> Jose
>>
>
>
>
> --
> *Christian Posta*
> http://www.christianposta.com/blog
> twitter: @christianposta

Re: Authenticating websockets endpoints.

Posted by Christian Posta <ch...@gmail.com>.
Jose,
Depends on which security mechanism you use. For example, for
spring-security, take a look here:

http://camel.apache.org/spring-security.html

You can set up the infrastructure for Spring Security to intercept and
validate the authentication, but the Authentication object being on the
exchange is your responsibility. You can add a processor that reads the
websocket payload and extracts the un/pw from there. You can also set up
the websocket connection to go over SSL to avoid sending plaintext.

http://camel.apache.org/websocket.html




On Fri, Aug 16, 2013 at 11:10 AM, Jose Espinosa <jo...@revinate.com> wrote:

> Hey all,
>
> I am using websockets to start on of my routes, now I am looking at
> adding security to my websockets end points.
>
> I took a look at camel security as described here
> http://camel.apache.org/camel-security.html and it works as
> advertised, but now I cann't find how to make my websocket client to
> authenticate.
>
> Any pointers on how to make my websocket client to authenticate with camel?
>
> Thank you very much,
> Jose
>



-- 
*Christian Posta*
http://www.christianposta.com/blog
twitter: @christianposta