spirng-boot中,基于既有的token验证方式,利用spring-security实现权限系统

spirng-boot中,基于既有的token验证方式,利用spring-security实现权限系统

用过spring-security的都应该能感受到,spring-security把authentication和authorization封装的比较死。默认的authorization是基于session的。利用session验证过的信息,保存进SecurityContext,权限系统再根据SecurityContext保存的用户权限相关信息,来进行权限管理。spring

可是在目前的场景中,服务器端每每要知足多端的验证方式,session的方式不容易和移动端配合的好。更多的是用一个token放在http header中进行验证。这种就须要绕开spring-security默认的authentication直接利用它的authorization。安全

在这里我演示一个在spring-security作方法级别拦截的方案。服务器

这里就是基于token的spring-boot安全拦截配置session

@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来构造SecurityContextapp

咱们再来看一下SecurityContext到底封装了什么。dom

public interface SecurityContext extends Serializable {

    Authentication getAuthentication();

    void setAuthentication(Authentication authentication);
}

Authentication而已。ide

public interface Authentication extends Principal, Serializable {spring-boot

Collection<? extends GrantedAuthority> getAuthorities();

Object getCredentials();

Object getDetails();

Object getPrincipal();

boolean isAuthenticated();
void setAuthenticated(boolean isAuthenticated) throws IllegalArgumentException;

}code

在这里咱们还要构造一个机遇token的Authentication接口的实现。在实现中对于权限来讲颇有用的就是getAuthorities方法。咱们只要给其封装最简单的SimpleGrantedAuthority就行了。token

这样咱们就能够给咱们的Controller方法作拦截了~

@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://mrchenatu.com/2016/12/...

相关文章
相关标签/搜索