[英]How to add a authorization filter to validate token and set security context in spring security?
I have a spring MVC application using spring security 4 and I want to add authorization based on the jwt token in the request.我有一个使用 spring security 4 的 spring MVC 应用程序,我想根据请求中的 jwt 令牌添加授权。 what I need to do in the filter is to我需要在过滤器中做的是
But when I start the application, I get an error saying An AuthenticationManager is required .但是当我启动应用程序时,我收到一条错误消息,指出An AuthenticationManager is required 。 I am not sure how the UserDetails service apply for my use case.我不确定 UserDetails 服务如何适用于我的用例。 Hence I have added a dummy return value for testing since without the UserDetailsService application is not working.因此,我添加了一个虚拟返回值进行测试,因为没有 UserDetailsService 应用程序将无法工作。 Any idea on this?对此有什么想法吗?
Spring security config class Spring 安全配置类
@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(
prePostEnabled = true
)
public class SpringSecurityConfig extends WebSecurityConfigurerAdapter {
@Autowired
@Qualifier("applicationUserService")
UserDetailsService userDetailsService;
@Override
public void configure(AuthenticationManagerBuilder authenticationManagerBuilder) throws Exception {
SecurityContextHolder.setStrategyName(SecurityContextHolder.MODE_INHERITABLETHREADLOCAL);
authenticationManagerBuilder
.userDetailsService(userDetailsService)
.passwordEncoder(bCryptPasswordEncoder());
}
@Override
protected void configure(HttpSecurity http) throws Exception {
http.csrf().disable().authorizeRequests()
.antMatchers(HttpMethod.GET, "/home").hasAnyRole("ADMIN")
.antMatchers(HttpMethod.GET, "/login").hasAnyRole("ADMIN")
.anyRequest().authenticated()
.and()
.addFilter(new AuthorizationFilter(authenticationManager()))
.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS);
}
@Bean
public BCryptPasswordEncoder bCryptPasswordEncoder() {
return new BCryptPasswordEncoder();
}
Authorization Filter class授权过滤器类
public class AuthorizationFilter extends BasicAuthenticationFilter {
private static final Logger LOGGER = LoggerFactory.getLogger(AuthorizationFilter.class);
public AuthorizationFilter(AuthenticationManager authenticationManager) {
super(authenticationManager);
}
@Override
protected void doFilterInternal(HttpServletRequest req, HttpServletResponse response, FilterChain chain) throws IOException, ServletException {
LOGGER.info("Request Info : {}", req.getRequestURI());
// get token
// fetch details from external API
// set security context
List<GrantedAuthority> authorities = new ArrayList<>();
authorities.add((GrantedAuthority) () -> "ROLE_ADMIN");
SecurityContextHolder.getContext().setAuthentication(new UsernamePasswordAuthenticationToken("user1", null, authorities));
LOGGER.info("security context principle:{}", SecurityContextHolder.getContext().getAuthentication().getPrincipal().toString());
LOGGER.info("authorities context:{}", SecurityContextHolder.getContext().getAuthentication().getAuthorities().toString());
chain.doFilter(req, response);
}
UserDetailsService implementation UserDetailsService 实现
@Service
@Qualifier("applicationUserService")
public class ApplicationUserServiceImpl implements UserDetailsService {
@Override
public UserDetails loadUserByUsername(String s) throws UsernameNotFoundException {
return new User("sidath", "123", emptyList());
}
}
Try this steps试试这个步骤
AbstractAuthenticationProcessingFilter
to evaluate request and return token.定义一个AbstractAuthenticationProcessingFilter
来评估请求和返回令牌。
public class AwesomeFilter extends AbstractAuthenticationProcessingFilter {
public AuthorizationFilter () {
super(new AntPathRequestMatcher("/your_post_url", "POST"));
}
@Override
public Authentication attemptAuthentication(HttpServletRequest request, HttpServletResponse response) {
// Evaluate request...
// Build your custom authentication token with the info
AwesomeToken token = new AwesomeToken();
// Authenticate token with authentication manager
return getAuthenticationManager().authenticate(token);
}
AuthenticationProvider
to supports your AwesomeToken
.定义一个AuthenticationProvider
来支持你的AwesomeToken
。 Spring Security will try to "supports" this. Spring Security 将尝试“支持”这一点。public class AwesomeProvider implements AuthenticationProvider {
@Override
public Authentication authenticate(Authentication authentication) throws AuthenticationException {
// Evaluate your custom token
// Call your API, etc
// Build your user authentication token details with authorities
Collection<? extends GrantedAuthority> auths = Collections.singletonList(new
SimpleGrantedAuthority("ROLE_ADMIN"));
AwesomeUserToken token = new AwesomeUserToken(auths);
// Return user token
return token;
}
@Override
public boolean supports(Class<?> authentication) {
return (AwesomeToken.class.isAssignableFrom(authentication));
}
@Override
public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
auth
.authenticationProvider(new AwesomeProvider());
}
@Override
public void addFilters(HttpSecurity http, AuthenticationManager authenticationManager) throws Exception {
AwesomeFilter filter = new AwesomeFilter();
filter.setAuthenticationManager(authenticationManager);
http
.addFilterAfter(filter, UsernamePasswordAuthenticationFilter.class);
}
Finally, when Spring Security detects the request with filter, it will try support with the provider and then return the token with the required authorities.最后,当 Spring Security 检测到带有过滤器的请求时,它将尝试支持提供者,然后返回具有所需权限的令牌。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.