This commit is contained in:
Vladimir Stankovic 2017-12-02 14:17:28 +01:00
parent 0ad4446978
commit 0292a78f91
5 changed files with 48 additions and 43 deletions

View File

@ -46,8 +46,8 @@ public class JwtAuthenticationProvider implements AuthenticationProvider {
String subject = jwsClaims.getBody().getSubject(); String subject = jwsClaims.getBody().getSubject();
List<String> scopes = jwsClaims.getBody().get("scopes", List.class); List<String> scopes = jwsClaims.getBody().get("scopes", List.class);
List<GrantedAuthority> authorities = scopes.stream() List<GrantedAuthority> authorities = scopes.stream()
.map(authority -> new SimpleGrantedAuthority(authority)) .map(SimpleGrantedAuthority::new)
.collect(Collectors.toList()); .collect(Collectors.toList());
UserContext context = UserContext.create(subject, authorities); UserContext context = UserContext.create(subject, authorities);

View File

@ -43,7 +43,7 @@ public class JwtTokenAuthenticationProcessingFilter extends AbstractAuthenticati
@Override @Override
public Authentication attemptAuthentication(HttpServletRequest request, HttpServletResponse response) public Authentication attemptAuthentication(HttpServletRequest request, HttpServletResponse response)
throws AuthenticationException, IOException, ServletException { throws AuthenticationException, IOException, ServletException {
String tokenPayload = request.getHeader(WebSecurityConfig.JWT_TOKEN_HEADER_PARAM); String tokenPayload = request.getHeader(WebSecurityConfig.AUTHENTICATION_HEADER_NAME);
RawAccessJwtToken token = new RawAccessJwtToken(tokenExtractor.extract(tokenPayload)); RawAccessJwtToken token = new RawAccessJwtToken(tokenExtractor.extract(tokenPayload));
return getAuthenticationManager().authenticate(new JwtAuthenticationToken(token)); return getAuthenticationManager().authenticate(new JwtAuthenticationToken(token));
} }

View File

@ -36,10 +36,10 @@ import com.svlada.security.auth.jwt.extractor.TokenExtractor;
@Configuration @Configuration
@EnableWebSecurity @EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter { public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
public static final String JWT_TOKEN_HEADER_PARAM = "X-Authorization"; public static final String AUTHENTICATION_HEADER_NAME = "Authorization";
public static final String FORM_BASED_LOGIN_ENTRY_POINT = "/api/auth/login"; public static final String AUTHENTICATION_URL = "/api/auth/login";
public static final String TOKEN_BASED_AUTH_ENTRY_POINT = "/api/**"; public static final String REFRESH_TOKEN_URL = "/api/auth/token";
public static final String TOKEN_REFRESH_ENTRY_POINT = "/api/auth/token"; public static final String API_ROOT_URL = "/api/**";
@Autowired private RestAuthenticationEntryPoint authenticationEntryPoint; @Autowired private RestAuthenticationEntryPoint authenticationEntryPoint;
@Autowired private AuthenticationSuccessHandler successHandler; @Autowired private AuthenticationSuccessHandler successHandler;
@ -53,15 +53,14 @@ public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
@Autowired private ObjectMapper objectMapper; @Autowired private ObjectMapper objectMapper;
protected AjaxLoginProcessingFilter buildAjaxLoginProcessingFilter() throws Exception { protected AjaxLoginProcessingFilter buildAjaxLoginProcessingFilter(String loginEntryPoint) throws Exception {
AjaxLoginProcessingFilter filter = new AjaxLoginProcessingFilter(FORM_BASED_LOGIN_ENTRY_POINT, successHandler, failureHandler, objectMapper); AjaxLoginProcessingFilter filter = new AjaxLoginProcessingFilter(loginEntryPoint, successHandler, failureHandler, objectMapper);
filter.setAuthenticationManager(this.authenticationManager); filter.setAuthenticationManager(this.authenticationManager);
return filter; return filter;
} }
protected JwtTokenAuthenticationProcessingFilter buildJwtTokenAuthenticationProcessingFilter() throws Exception { protected JwtTokenAuthenticationProcessingFilter buildJwtTokenAuthenticationProcessingFilter(List<String> pathsToSkip, String pattern) throws Exception {
List<String> pathsToSkip = Arrays.asList(TOKEN_REFRESH_ENTRY_POINT, FORM_BASED_LOGIN_ENTRY_POINT); SkipPathRequestMatcher matcher = new SkipPathRequestMatcher(pathsToSkip, pattern);
SkipPathRequestMatcher matcher = new SkipPathRequestMatcher(pathsToSkip, TOKEN_BASED_AUTH_ENTRY_POINT);
JwtTokenAuthenticationProcessingFilter filter JwtTokenAuthenticationProcessingFilter filter
= new JwtTokenAuthenticationProcessingFilter(failureHandler, tokenExtractor, matcher); = new JwtTokenAuthenticationProcessingFilter(failureHandler, tokenExtractor, matcher);
filter.setAuthenticationManager(this.authenticationManager); filter.setAuthenticationManager(this.authenticationManager);
@ -82,26 +81,32 @@ public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
@Override @Override
protected void configure(HttpSecurity http) throws Exception { protected void configure(HttpSecurity http) throws Exception {
List<String> permitAllEndpointList = Arrays.asList(
AUTHENTICATION_URL,
REFRESH_TOKEN_URL,
"/console"
);
http http
.csrf().disable() // We don't need CSRF for JWT based authentication .csrf().disable() // We don't need CSRF for JWT based authentication
.exceptionHandling() .exceptionHandling()
.authenticationEntryPoint(this.authenticationEntryPoint) .authenticationEntryPoint(this.authenticationEntryPoint)
.and() .and()
.sessionManagement() .sessionManagement()
.sessionCreationPolicy(SessionCreationPolicy.STATELESS) .sessionCreationPolicy(SessionCreationPolicy.STATELESS)
.and() .and()
.authorizeRequests() .authorizeRequests()
.antMatchers(FORM_BASED_LOGIN_ENTRY_POINT).permitAll() // Login end-point .antMatchers(permitAllEndpointList.toArray(new String[permitAllEndpointList.size()]))
.antMatchers(TOKEN_REFRESH_ENTRY_POINT).permitAll() // Token refresh end-point .permitAll()
.antMatchers("/console").permitAll() // H2 Console Dash-board - only for testing .and()
.and() .authorizeRequests()
.authorizeRequests() .antMatchers(API_ROOT_URL).authenticated() // Protected API End-points
.antMatchers(TOKEN_BASED_AUTH_ENTRY_POINT).authenticated() // Protected API End-points .and()
.and() .addFilterBefore(new CustomCorsFilter(), UsernamePasswordAuthenticationFilter.class)
.addFilterBefore(new CustomCorsFilter(), UsernamePasswordAuthenticationFilter.class) .addFilterBefore(buildAjaxLoginProcessingFilter(AUTHENTICATION_URL), UsernamePasswordAuthenticationFilter.class)
.addFilterBefore(buildAjaxLoginProcessingFilter(), UsernamePasswordAuthenticationFilter.class) .addFilterBefore(buildJwtTokenAuthenticationProcessingFilter(permitAllEndpointList,
.addFilterBefore(buildJwtTokenAuthenticationProcessingFilter(), UsernamePasswordAuthenticationFilter.class); API_ROOT_URL), UsernamePasswordAuthenticationFilter.class);
} }
} }

View File

@ -51,7 +51,7 @@ public class RefreshTokenEndpoint {
@RequestMapping(value="/api/auth/token", method=RequestMethod.GET, produces={ MediaType.APPLICATION_JSON_VALUE }) @RequestMapping(value="/api/auth/token", method=RequestMethod.GET, produces={ MediaType.APPLICATION_JSON_VALUE })
public @ResponseBody JwtToken refreshToken(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException { public @ResponseBody JwtToken refreshToken(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException {
String tokenPayload = tokenExtractor.extract(request.getHeader(WebSecurityConfig.JWT_TOKEN_HEADER_PARAM)); String tokenPayload = tokenExtractor.extract(request.getHeader(WebSecurityConfig.AUTHENTICATION_HEADER_NAME));
RawAccessJwtToken rawToken = new RawAccessJwtToken(tokenPayload); RawAccessJwtToken rawToken = new RawAccessJwtToken(tokenPayload);
RefreshToken refreshToken = RefreshToken.create(rawToken, jwtSettings.getTokenSigningKey()).orElseThrow(() -> new InvalidJwtToken()); RefreshToken refreshToken = RefreshToken.create(rawToken, jwtSettings.getTokenSigningKey()).orElseThrow(() -> new InvalidJwtToken());

View File

@ -4,5 +4,5 @@
<logger name="org.springframework.web" level="DEBUG"/> <logger name="org.springframework.web" level="DEBUG"/>
<logger name="org.springframework.security" level="DEBUG"/> <logger name="org.springframework.security" level="DEBUG"/>
<logger name="org.springframework" level="ERROR"/> <logger name="org.springframework" level="ERROR"/>
<logger name="com.svlada" level="ALL"/> <logger name="com.svlada" level="DEBUG"/>
</configuration> </configuration>