我是新来的春天,假装和探索几天。 我能够对我们的受保护资源(用户名/密码)进行身份验证请求,并在后续请求标头中使用auth服务返回的JWT令牌。 但是,我想在令牌过期时使用相同的凭证来调用auth服务.Spring云有OAuth2FeignRequestInterceptor,它使用客户端ID和密钥完全相同。
用于处理用户名和密码生成的令牌的任何此类自定义拦截器?
答案 0 :(得分:1)
如果您的JWT令牌提供程序符合OAuth 2.0,则可以使用OAuth2FeignRequestInterceptor
对象配置OAuth2ProtectedResourceDetails
。此对象是所有OAuth 2.0授权类型信息的基类。在您的情况下,我建议使用ResourceOwnerPasswordResourceDetails
代替。这将允许您使用用户名和密码配置拦截器。
@Configuration
public class OAuth2RequestInterceptorConfiguration {
@Bean
public OAuth2FeignRequestInterceptor requestInterceptor() {
OAuth2ClientContext clientContext = new DefaultOAuth2ClientContext();
OAuth2ProtectedResourceDetails resourceDetails =
new ResourceOwnerPasswordResourceDetails();
resourceDetails.setUsername("username");
resourceDetails.setPassword("password");
return new OAuth2FeignRequestInterceptor(clientContext, resourceDetails);
}
}
对于其他情况,您需要创建自己的RequestInterceptor
public class MyRequestInterceptor implements RequestInterceptor {
private String jwt;
private LocalDateTime expirationDate;
@Override
public void apply(RequestTemplate requestTemplate) {
/* validate and refresh your token, this sample is not thread safe */
if (LocalDateTime.now().isAfter(expirationDate)) {
requestToken();
}
/* use the token */
requestTemplate.header("Authorization: Bearer " + this.jwt);
}
}
答案 1 :(得分:0)
用例并不完全清楚,但也许下面的代码片段也很有用。我们的服务需要签名的OAuth Bearer JWT 访问令牌。您可以看到我们在JWT到期时明确验证,并且当JWT令牌过期时我们会返回错误。在我们的设置中,消费者有责任在发生此情况时捕获此错误并使用刷新令牌(以检索新的访问令牌)。
希望这有点澄清。
维姆
/**
* Created by Wim Van den Brande on 11/02/2018.
*/
@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class SecurityConfig extends WebSecurityConfigurerAdapter {
private static final Logger LOGGER = LoggerFactory.getLogger(SecurityConfig.class);
public static final String SCOPE = "scope";
public static final String HEADER_AUTHORIZATION = "Authorization";
public static final String HEADER_BEARER = "Bearer";
public static final String HEADER_ENCRYPTION_TYPE = "Encryption-Type";
public static final String ASSYMETRIC_ENCRYPTION_RS256 = "RS256";
@Value("${CS.signedPublicKey}")
private String signedPublicKey;
@Autowired
private Key signinKey;
@Override
protected void configure(HttpSecurity http) throws Exception {
// TODO : to enable CSRF
http.httpBasic().and().csrf().disable();
TokenAuthenticationFilter tokenFilter = new TokenAuthenticationFilter();
http.addFilterBefore(tokenFilter, BasicAuthenticationFilter.class);
}
@Override
public void configure(WebSecurity web) throws Exception {
web.ignoring().antMatchers("/admin", "/v2/api-docs", "/configuration/ui", "/swagger-resources", "/configuration/security", "/swagger-ui.html", "/webjars/**");
}
// Actual Implementation of Token Based Authentication
// ---------------------------------------------------
public class TokenAuthenticationFilter extends GenericFilterBean {
@Override
public void doFilter(final ServletRequest request, final ServletResponse response, final FilterChain chain) throws IOException, ServletException {
final HttpServletRequest httpRequest = (HttpServletRequest) request;
final HttpServletResponse httpResponse = (HttpServletResponse) response;
String authorizationHeader = httpRequest.getHeader(HEADER_AUTHORIZATION);
if (authorizationHeader == null) {
httpResponse.sendError(HttpServletResponse.SC_UNAUTHORIZED, String.format("Request doesn't contain header %s.", HEADER_AUTHORIZATION));
return;
}
String[] authorizationHeaderValues = authorizationHeader.split("\\s+");
if (authorizationHeaderValues.length != 2 || !authorizationHeaderValues[0].equals(HEADER_BEARER)) {
httpResponse.sendError(HttpServletResponse.SC_UNAUTHORIZED, String.format("AuthorizationHeader %s is an invalid header ", authorizationHeader));
return;
}
String accessToken = authorizationHeaderValues[1];
Claims jwtClaims;
// Symmetric Encryption is our default
if (httpRequest.getHeader(HEADER_ENCRYPTION_TYPE) == null || !httpRequest.getHeader(HEADER_ENCRYPTION_TYPE).equals(ASSYMETRIC_ENCRYPTION_RS256)) {
if (LOGGER.isDebugEnabled()) {
LOGGER.debug("Using Symmetric algorithm");
}
try {
jwtClaims = Jwts.parser().setSigningKey(signinKey).parseClaimsJws(accessToken).getBody();
}
catch (ExpiredJwtException e) {
httpResponse.sendError(HttpServletResponse.SC_UNAUTHORIZED, "JSON Web Token has expired");
return;
}
}
在这里输入代码
答案 2 :(得分:0)
您可以尝试以下操作:
public class FeignConfiguration {
@Value("${security.jwt.token}")
private String jwtToken;
@Bean
public RequestInterceptor requestInterceptor() {
@Override
public void apply(RequestTemplate requestTemplate) {
requestTemplate.header("Authorization", jwtToken);
}
}
}