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/...

相關文章
相關標籤/搜索