上一篇说了如何去定义自定义登录界面,现在来说下请求url的控制
请求URL控制
http.authorizeRequests()主要是对url进行控制
1.anyRequest()
在之前认证过程中我们就已经使用过anyRequest(),表示匹配所有的请求。一般情况下此方法都会使用,设置全部内容都需要进行认证。
anyRequest().authenticated();
2.antMatcher()
参数是不定向参数,每个参数是一个ant表达式,用于匹配URL规则。
public C antMatchers(String... antPatterns)
规则:? 匹配一个字符, * 匹配0个或多个字符, ** 匹配0个或多个目录
3.regexMatchers()
使用正则表达式进行匹配。和antMatchers()主要的区别就是参数,antMatchers()参数是ant表达式,regexMatchers()参数是正则表达式。
.regexMatchers(".+[.]js").permitAll()
无论是antMatchers()还是regexMatchers()都具有两个参数的方法,其中第一个参数都是HttpMethod,表示请求方式,当设置了HttpMethod后表示只有设定的特定的请求方式才执行对应的权限设置。
Spring Security匹配了URL后调用了permitAll()表示不需要认证,随意访问。在Spring Security中提供了多种内置控制。
1.permitAll()permitAll()表示所匹配的URL任何人都允许访问。
2.authenticated() 表示所匹配的URL都需要被认证才能访问。
3. anonymous() 表示可以匿名访问匹配的URL。和permitAll()效果类似
4. denyAll() 表示所匹配的URL都不允许被访问。
5.rememberMe()被“remember me”的用户允许访问
6.fullyAuthenticated() 如果用户不是被remember me的,才可以访问。
http.authorizeRequests()
.antMatchers("/showLogin","/showFail").permitAll()
.antMatchers("/js/**").permitAll()
// .antMatchers("/**/*.js").permitAll() 只要是js文件都可以放行
// .regexMatchers("/js/.*").permitAll() 支持正则
.anyRequest().authenticated();
请求权限控制
1.权限控制
1.hasAuthority(String) 判断用户是否具有特定的权限,用户的权限是在自定义登录逻辑中创建User对象时指定的。
在配置类中通过hasAuthority(“admin”)设置具有admin权限时才能访问。
2.hasAnyAuthority(String ...) 如果用户具备给定权限中某一个,就允许访问。
下面代码中由于大小写和用户的权限不相同,所以用户无权访问/main1.html
.antMatchers("/main1.html").hasAnyAuthority("adMin","admiN")
3. hasRole(String) 如果用户具备给定角色就允许访问。否则出现403。
参数取值来源于自定义登录逻辑UserDetailsService实现类中创建User对象时给User赋予的授权。 在给用户赋予角色时角色需要以:ROLE_ 开头,后面添加角色名称。例如:ROLE_abc 其中abc是角色名,ROLE_是固定的字符开头。使用hasRole()时参数也只写abc即可。否则启动报错。
.antMatchers("/main1.html").hasRole("abc")
4.hasAnyRole(String ...) 如果用户具备给定角色的任意一个,就允许被访问
5.hasIpAddress(String) 如果请求是指定的IP就运行访问。可以通过request.getRemoteAddr()获取ip地址。
.antMatchers(**"/main1.html"**).hasAuthority(**"admin"**)
http.authorizeRequests()
.antMatchers("/showLogin","/showFail").permitAll()
// .antMatchers("/authority").hasAuthority("abc") // 用户权限中有 admin1.admin2
.antMatchers("/authority").hasAnyAuthority("abc","admin1") // 用户权限中有 abc.admin1 中的一个就能通过
.antMatchers("/role").hasRole("admin3") // // 用户有角色 admin3
.antMatchers("/ip").hasIpAddress("192.155.131.3") // // 用户有角色 admin3
.antMatchers("/abc").denyAll("abc")
.anyRequest().authenticated();
基于表达式的访问控制
1.access()方法使用
登录用户权限判断实际上底层实现都是调用access(表达式),可以通过access()实现和之前学习的权限控制完成相同的功能。
以hasRole和permitAll举例
下面代码和直接使用permitAll()和hasRole()是等效的。
可以使用自定义方法,例如判断登录用户是否具有访问当前URL权限。
新建一个接口
public interface MyService {
boolean hasPermission(HttpServletRequest request, Authentication authentication);
}
@Component
public class MyServiceImpl implements MyService {
@Override
public boolean hasPermission(HttpServletRequest request, Authentication authentication) {
Object obj = authentication.getPrincipal();
if(obj instanceof UserDetails){
UserDetails user = (UserDetails) obj;
Collection<? extends GrantedAuthority> authorities = user.getAuthorities();
return authorities.contains(new SimpleGrantedAuthority(request.getRequestURI()));
}
return false;
}
}
然后修改配置类方法
在access中通过@bean的id名.方法(参数)的形式进行调用
// url 拦截 (授权)
http.authorizeRequests()
.antMatchers("/login.html").access("permitAll")
.antMatchers("/fail.html").permitAll()
.anyRequest().access("@myServiceImpl.hasPermission(request,authentication)");