[英]Spring Security java configuration confusion
为什么以下配置没有提示登录? 当我尝试访问/ public / user时 ,出现错误403(访问被拒绝)。 但是,如果我取消注释WebServiceSecurityConfiguration.configure
注释行,则会根据需要将我重定向到登录页面。 为什么antMatcher首先匹配不同的路径,所以正确配置from-log需要这些行。 我猜这里有一些冲突,错误地配置了AuthenticationEntryPoint
,但是我真的不知道该如何发生。 我要实现的目标是配置两个安全链,一个安全链用于登录路径以获得JWT令牌,另一个安全链用于Web服务针对该令牌进行身份验证。 在没有注释的情况下,一切都可以正常运行,但是我偶然地注意到,没有它们,表单登录就停止了工作,对此感到非常困惑。
@Configuration
@Profile("javasecurity")
@Order(11)
@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class SecurityConfiguration extends WebSecurityConfigurerAdapter {
@Autowired
private TokenHandler tokenHandler;
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.inMemoryAuthentication()
.withUser("user").password("password").authorities(new SimpleGrantedAuthority("ROLE_USER")).and()
.withUser("admin").password("password").authorities(
new SimpleGrantedAuthority("ROLE_USER"),
new SimpleGrantedAuthority("ROLE_ADMIN")).and()
.withUser("guest").password("guest").authorities(new SimpleGrantedAuthority("ROLE_GUEST"));
}
@Override
@Bean
public UserDetailsService userDetailsServiceBean() throws Exception {
return super.userDetailsServiceBean();
}
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.authorizeRequests()
.antMatchers("/public/**")
.permitAll()
.and()
.formLogin()
.successHandler(authenticationSuccessHandler())
.and()
.logout();
}
@Bean
public AuthenticationSuccessHandler authenticationSuccessHandler() {
return new AuthenticationSuccessHandler() {
public void onAuthenticationSuccess(HttpServletRequest request, HttpServletResponse response,
Authentication authentication) throws IOException, ServletException {
tokenHandler.setToken(response, authentication.getName());
response.getWriter().println("User authenticated and cookie sent");
response.flushBuffer();
}
};
}
@Configuration
@Profile("javasecurity")
@Order(10)
public static class WebServiceSecurityConfiguration extends WebSecurityConfigurerAdapter {
@Autowired
private TestAuthenticationFilter testAuthenticationFilter;
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.authorizeRequests()
.antMatchers("/secured/**")
.authenticated();
// .and()
// .antMatcher("/secured/**")
// .securityContext().securityContextRepository(new NullSecurityContextRepository())
// .and()
// .addFilterAt(testAuthenticationFilter, UsernamePasswordAuthenticationFilter.class);
}
}
-
@Component("TestAuthenticationFilter")
public class TestAuthenticationFilter extends GenericFilterBean {
@Autowired
private TokenHandler tokenHandler;
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
throws IOException, ServletException {
System.out.println("TestAuthenticationFilter doFitler");
attemptAuthentication((HttpServletRequest) request);
chain.doFilter(request, response);
clearAuthentication();
System.out.println("doFitler end");
}
public void attemptAuthentication(HttpServletRequest request) {
try {
UserDetails user = tokenHandler.loadUserFromToken(request);
UsernamePasswordAuthenticationToken auth = new UsernamePasswordAuthenticationToken(user, user.getPassword());
SecurityContextHolder.getContext().setAuthentication(auth);
} catch (Exception e) {
// Do nothing
}
}
public void clearAuthentication() {
SecurityContextHolder.getContext().setAuthentication(null);
}
@Configuration
public static class DisableFilterRegistration {
@Autowired
private TestAuthenticationFilter filter;
@Bean
public FilterRegistrationBean disablerBean() {
FilterRegistrationBean bean = new FilterRegistrationBean(filter);
bean.setEnabled(false);
return bean;
}
}
}
-
@Component("TokenHandler")
public class TokenHandler {
@Autowired(required = false)
private UserDetailsService userDetailsService;
public void setToken(HttpServletResponse response, String username) {
response.addCookie(new Cookie("user", username));
}
public UserDetails loadUserFromToken(HttpServletRequest request) throws BadCredentialsException {
Cookie[] cookies = request.getCookies();
Cookie token = null;
for (Cookie c : cookies) {
if (c.getName().equals("user")) {
token = c;
break;
}
}
if (token == null)
return null;
else
return userDetailsService.loadUserByUsername(token.getValue());
}
}
-
@RestController
@RequestMapping("/public")
public class PublicController {
@GetMapping("/norole")
public String noRole() {
return "no role";
}
@GetMapping("/user")
@PreAuthorize("hasRole('ROLE_USER')")
public String roleUser() {
return "role_user";
}
}
-
@RestController
@RequestMapping("/secured")
public class SecuredController {
@GetMapping("/user")
@PreAuthorize("hasRole('ROLE_USER')")
public String roleUser() {
return "role_user";
}
@GetMapping("/admin")
@PreAuthorize("hasRole('ROLE_ADMIN')")
public String roleAdmin() {
return "role_admin";
}
@GetMapping("/norole")
public String noRole() {
return "no role";
}
}
声明添加后,登录源再次起作用
http.antMatcher("/secured/**")
作为WebServiceSecurityConfiguration.configure
的第一个调用。 这是否意味着没有它,配置将否定在此特定配置之后配置的表单登录? 另外,似乎antMatcher
的位置可以是任意的,是这种情况吗? 有人可以解释一下那里到底发生了什么吗?
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.