将JWT与Spring Security OAuth结合使用

首先,我们需要在我们的pom.xml中添加spring-security-jwt依赖项:

<dependency> <groupId>org.springframework.security</groupId> <artifactId>spring-security-jwt</artifactId> </dependency>

请注意,我们需要将spring-security-jwt依赖项添加到Authorization Server和Resource Server

3.授权服务器

接下来,我们将配置我们的授权服务器以使用JwtTokenStore - 如下所示:

@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; } }

请注意,我们在JwtAccessTokenConverter中使用对称密钥来签署我们的令牌 - 这意味着我们还需要为Resources Server使用相同的密钥

4.资源服务器

现在,让我们看看我们的资源服务器配置 - 这与授权服务器的配置非常相似:

@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; } }

请记住,我们将这两个服务器定义为完全独立且可独立部署。这就是我们需要在新配置中再次声明一些相同bean的原因。

5.令牌中的自定义Claims

现在让我们设置一些基础设施,以便能够在Access Token中添加一些自定义声明

框架提供的标准声明都很好,但大多数时候我们需要在令牌中使用一些额外的信息才能在客户端使用。框架提供的标准声明都很好,但大多数时候我们需要在令牌中使用一些额外的信息才能在客户端使用

我们将定义TokenEnhancer以使用这些附加声明来自定义我们的访问令牌

在下面的示例中,我们将使用此CustomTokenEnhancer向我们的访问令牌添加一个额外的字段“组织”

public class CustomTokenEnhancer implements TokenEnhancer { @Override public OAuth2AccessToken enhance( OAuth2AccessToken accessToken, OAuth2Authentication authentication) { Map<String, Object> additionalInfo = new HashMap<>(); additionalInfo.put( "organization", authentication.getName() + randomAlphabetic(4)); ((DefaultOAuth2AccessToken) accessToken).setAdditionalInformation( additionalInfo); return accessToken; } }

然后,我们将它连接到我们的授权服务器配置 - 如下所示:

@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(); }

启动并运行此新配置 :

{ "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。使用JS Client中的Access Token

最后,我们希望在AngualrJS客户端应用程序中使用令牌信息。我们将使用angular-jwt库。

那么我们要做的就是在index.html中使用“组织”声明:

<p>{{organization}}</p> <script type="text/javascript" src="http://cdn.rawgit.com/auth0/angular-jwt/master/dist/angular-jwt.js"> </script> <script> var app = angular.module('myApp', ["ngResource","ngRoute", "ngCookies", "angular-jwt"]); app.controller('mainCtrl', function($scope, $cookies, jwtHelper,...) { $scope.organiztion = ""; function getOrganization(){ var token = $cookies.get("access_token"); var payload = jwtHelper.decodeToken(token); $scope.organization = payload.organization; } ... }); 6.访问资源服务器上的额外声明

但是,我们如何在资源服务器端访问该信息?

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/zwwxss.html