[英]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.