用过spring-security的都应该能感觉到,spring-security把authentication和authorization封装的比较死。默认的authorization是基于session的。利用session验证过的信息,保存进SecurityContext,权限系统再根据SecurityContext保存的用户权限相关信息,来进行权限管理。
但是在目前的场景中,服务器端往往要满足多端的验证方式,session的方式不容易和移动端配合的好。更多的是用一个token放在http header中进行验证。这种就需要绕开spring-security默认的authentication直接利用它的authorization。
在这里我演示一个在spring-security做方法级别拦截的方案。
这里就是基于token的spring-boot安全拦截配置
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32
|
@Configuration @EnableWebSecurity @EnableGlobalMethodSecurity(prePostEnabled = true) @Order(1) public class TokenBasedSecurityConfig extends WebSecurityConfigurerAdapter { @Override protected void configure(HttpSecurity http) { try { http.addFilterBefore(... SecurityContextPersistenceFilter.class); http.securityContext().securityContextRepository(new SecurityContextRepository() { @Override public SecurityContext loadContext(HttpRequestResponseHolder requestResponseHolder) { ... } @Override public void saveContext(SecurityContext context, HttpServletRequest request, HttpServletResponse response) { ... } @Override public boolean containsContext(HttpServletRequest request) { ... } }); } catch (Exception e) { e.printStackTrace(); } } }
|
在这里,我们要做的其实就是设置重在SecurityContextRepository
。这个实体在spring security启动中要传递给SecurityContextPersistenceFilter
。这个filter根据request来加载SecurityContext
。而SecurityContextPersistenceFilter
就是从其内部的SecurityContextRepository
来加载SecurityContext
的。所以我们就需要重载上面代码中的三个方法,根据request来构造SecurityContext
。
我们再来看一下SecurityContext
到底封装了什么。
1 2 3 4 5 6
|
public interface SecurityContext extends Serializable { Authentication getAuthentication(); void setAuthentication(Authentication authentication); }
|
Authentication而已。
public interface Authentication extends Principal, Serializable {
Collection extends GrantedAuthority> getAuthorities();
Object getCredentials();
Object getDetails();
Object getPrincipal();
boolean isAuthenticated();
void setAuthenticated(boolean isAuthenticated) throws IllegalArgumentException;
}
在这里我们还要构造一个机遇token的Authentication接口的实现。在实现中对于权限来说很有用的就是getAuthorities
方法。我们只要给其封装最简单的SimpleGrantedAuthority
就好了。
这样我们就可以给我们的Controller方法做拦截了~
1 2 3 4 5 6 7 8 9 10
|
@RestController @RequestMapping(value = "test") public class TestController { @PreAuthorize("hasAuthority('super_admin')") @RequestMapping(value = "hello", method = RequestMethod.GET) public String superHello(@RequestParam String domain) { return new String("super hello"); } }
|
转载自演道,想查看更及时的互联网产品技术热点文章请点击http://go2live.cn
About The Author
bjmayor
程序员,码农,php,python,ios,android,go,产品经理,创业。