SpringSecurity提供了匿名登录功能,让我们不登录也能访问。比如/anoy路径及子路径都能匿名访问,配置如下:
@Configuration
public class MySecurityConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
http.authorizeRequests()
.antMatchers("/anoy/*").anonymous()
.anyRequest()
.authenticated()
.and()
.formLogin()
.permitAll()
.and()
.sessionManagement()
.sessionFixation()
.newSession()
.maximumSessions(1);
}
}
同时增加controller:
@RestController
@RequestMapping("/anoy")
public class AnoyController {
@RequestMapping("/foo")
public String foo(Authentication authentication) {
return "foo:" + authentication;
}
}
访问http://localhost:8080/anoy/foo,看到foo:null。可知不需要登录也能访问。将foo方法改成:
@RequestMapping("/foo")
public String foo() {
Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
return "foo:" + authentication;
}
访问http://localhost:8080/anoy/foo,看到foo:AnonymousAuthenticationToken [Principal=anonymousUser, Credentials=[PROTECTED], Authenticated=true, Details=WebAuthenticationDetails [RemoteIpAddress=0:0:0:0:0:0:0:1, SessionId=null], Granted Authorities=[ROLE_ANONYMOUS]]。从上面可知SecurityContextHolder.getContext().getAuthentication()和通过参数注入的Authentication是不相同的。
源码分析
AnonymousAuthenticationFilter
public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain)
throws IOException, ServletException {
if (SecurityContextHolder.getContext().getAuthentication() == null) {
Authentication authentication = createAuthentication((HttpServletRequest) req);
SecurityContext context = SecurityContextHolder.createEmptyContext();
context.setAuthentication(authentication);
SecurityContextHolder.setContext(context);
if (this.logger.isTraceEnabled()) {
this.logger.trace(LogMessage.of(() -> "Set SecurityContextHolder to "
+ SecurityContextHolder.getContext().getAuthentication()));
}
else {
this.logger.debug("Set SecurityContextHolder to anonymous SecurityContext");
}
}
else {
if (this.logger.isTraceEnabled()) {
this.logger.trace(LogMessage.of(() -> "Did not set SecurityContextHolder since already authenticated "
+ SecurityContextHolder.getContext().getAuthentication()));
}
}
chain.doFilter(req, res);
}
判断SecurityContextHolder.getContext().getAuthentication()是否为空,如果不为空则是认证登录。否则设置匿名用户和角色。并将匿名用户设置到SecurityContextHolder中。
protected Authentication createAuthentication(HttpServletRequest request) {
AnonymousAuthenticationToken token = new AnonymousAuthenticationToken(this.key, this.principal,
this.authorities);
token.setDetails(this.authenticationDetailsSource.buildDetails(request));
return token;
}
createAuthentication创建用户名为anonymousUser,角色为ROLE_ANONYMOUS的匿名用户。
标签:getAuthentication,springSecurity,SecurityContextHolder,Authentication,getContext From: https://www.cnblogs.com/shigongp/p/17366891.html