jwt token & spring oauth2

原文链接:http://www.baeldung.com/spring-security-oauth-jwt

1. Overview

In this tutorial we’ll discuss how to get our Spring Security OAuth2 implementation to make use of JSON Web Tokens.

We’re also continuing to built on top of the previous article in this OAuth series.

2. Maven Configuration

First, we need to add spring-security-jwt dependency to our pom.xml:


     org.springframework.security
     spring-security-jwt

Note that we need to add spring-security-jwt dependency to both Authorization Server and Resource Server.

3. Authorization Server

Next, we will configure our Authorization Server to use JwtTokenStore – as follows:

@Configuration

@EnableAuthorizationServer

public class OAuth2AuthorizationServerConfig extends AuthorizationServerConfigurerAdapter {

     @Override

     public void configure (AuthorizationServerEndpointsConfigurer endpoints ) throws Exception {

        endpoints . tokenStore (tokenStore ())

                  . accessTokenConverter (accessTokenConverter ())

                  . authenticationManager (authenticationManager );

     }

     @Bean
     public TokenStore tokenStore () {
         return new JwtTokenStore (accessTokenConverter ());
     }

     @Bean
     public JwtAccessTokenConverter accessTokenConverter () {
        JwtAccessTokenConverter converter = new JwtAccessTokenConverter ();
        converter . setSigningKey ( "123" );
         return converter ;
     }

     @Bean
     @Primary
     public DefaultTokenServices tokenServices () {
        DefaultTokenServices defaultTokenServices = new DefaultTokenServices ();
        defaultTokenServices . setTokenStore (tokenStore ());
        defaultTokenServices . setSupportRefreshToken ( true );
         return defaultTokenServices ;
     }
}

Note that we used a symmetric key in our JwtAccessTokenConverter to sign our tokens – which means we will need to use the same exact key for the Resources Server as well.

4. Resource Server

Now, let’s take a look at our Resource Server configuration – which is very similar to the config of the Authorization Server:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

@Configuration

@EnableResourceServer

public class OAuth2ResourceServerConfig extends ResourceServerConfigurerAdapter {

    @Override

    public void configure(ResourceServerSecurityConfigurer config) {

        config.tokenServices(tokenServices());

    }

 

    @Bean

    public TokenStore tokenStore() {

        return new JwtTokenStore(accessTokenConverter());

    }

 

    @Bean

    public JwtAccessTokenConverter accessTokenConverter() {

        JwtAccessTokenConverter converter = new JwtAccessTokenConverter();

        converter.setSigningKey("123");

        return converter;

    }

 

    @Bean

    @Primary

    public DefaultTokenServices tokenServices() {

        DefaultTokenServices defaultTokenServices = new DefaultTokenServices();

        defaultTokenServices.setTokenStore(tokenStore());

        return defaultTokenServices;

    }

}

Keep in mind that we’re defining these two servers as entirely separate and independently deployable. That’s the reason we need to declare some of the same beans again here, in the new configuration.

5. Custom Claims in the Token

Let’s now set up some infrastructure to be able to add a few custom claims in the Access Token. The standard claims provided by the framework are all well and good, but most of the time we’ll need some extra information in the token to utilize on the client side.

We’ll define a TokenEnhancer to customize our Access Token with these additional claims.

In the following example, we will add an extra field “organization” to our Access Token – with this CustomTokenEnhancer:

1

2

3

4

5

6

7

8

9

10

11

public class CustomTokenEnhancer implements TokenEnhancer {

    @Override

    public OAuth2AccessToken enhance(

     OAuth2AccessToken accessToken,

     OAuth2Authentication authentication) {

        Map additionalInfo = new HashMap<>();

        additionalInfo.put("organization", authentication.getName() + randomAlphabetic(4));

        ((DefaultOAuth2AccessToken) accessToken).setAdditionalInformation(additionalInfo);

        return accessToken;

    }

}

Then, we’ll wire that into our Authorization Server configuration – as follows:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

@Override

public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception {

    TokenEnhancerChain tokenEnhancerChain = new TokenEnhancerChain();

    tokenEnhancerChain.setTokenEnhancers(

      Arrays.asList(tokenEnhancer(), accessTokenConverter()));

 

    endpoints.tokenStore(tokenStore())

             .tokenEnhancer(tokenEnhancerChain)

             .authenticationManager(authenticationManager);

}

 

@Bean

public TokenEnhancer tokenEnhancer() {

    return new CustomTokenEnhancer();

}

With this new configuration up and running – here’s what a token token payload would look like:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

{

    "user_name": "john",

    "scope": [

        "foo",

        "read",

        "write"

    ],

    "organization": "johnIiCh",

    "exp": 1458126622,

    "authorities": [

        "ROLE_USER"

    ],

    "jti": "e0ad1ef3-a8a5-4eef-998d-00b26bc2c53f",

    "client_id": "fooClientIdPassword"

}

5.1. Use the Access Token in the JS Client

Finally, we’ll want to make use of the token information over in our AngualrJS client application. We’ll use the angular-jwt library for that.

So what we’re going to do is we’re going to make use of the “organization” claim in our index.html:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

 

 

你可能感兴趣的:(oauth2)