簡體   English   中英

不使用角色僅進行身份驗證的Spring安全授權

[英]Spring security authorization without authentication using role only

我正在嘗試在我們的應用程序中實現spring security的授權元素。 我們有一個外部身份驗證過程,只想使用Spring Security阻止沒有特定角色的人訪問某些URL。 我們希望在http請求中將用戶角色作為標頭傳遞,並確定用戶是否可以在不知道其名稱或密碼的情況下查看該url。

看了很多文檔之后,我還沒有看到有人這樣做的示例,但是我相信,與此相伴的方法是擴展AbstractPreAuthenticatedProcessingFilter並像這樣從請求中獲取角色:

public class RequestHeaderPreAuthenticatedProcessingFilterImpl extends
    AbstractPreAuthenticatedProcessingFilter {

   private final String PRINCIPAL_REQUEST_HEADER = "user-role";

   private final boolean EXCEPTION_IF_HEADER_MISSING = true;

   @Override
   protected Object getPreAuthenticatedPrincipal(HttpServletRequest request) {
       String principal = request.getHeader(PRINCIPAL_REQUEST_HEADER);
       if (principal == null && EXCEPTION_IF_HEADER_MISSING) {
           throw new PreAuthenticatedCredentialsNotFoundException(PRINCIPAL_REQUEST_HEADER
                + " header not found in request.");
       }
       return principal;

   }

   @Override
   protected Object getPreAuthenticatedCredentials(HttpServletRequest request) {
       return "N/A";
   }

}

我的問題是:
1)這是解決問題的正確方法嗎?
2)返回作為委托人的正確的事情是什么? 它是角色還是包含有關虛擬用戶信息的UserDetails對象?
3)是否可以將其插入預定義的Spring對象中,還是必須為Authentication Manager,Provider等創建具體的實現?

我解決此問題的方法是通過創建AuthenticationProvider和AbstractPreAuthenticatedProcessingFilter的實現。 這使我可以從請求中獲取相關標頭,將主體設置為角色列表,然后自己進行身份驗證。

我對AbstractPreAuthenticatedProcessingFilter的實現:

public class RequestHeaderPreAuthenticatedProcessingFilterImpl extends
    AbstractPreAuthenticatedProcessingFilter {

private final String PRINCIPAL_REQUEST_HEADER = "user-role";

private boolean exceptionIfHeaderMissing = true;

    @Override
    protected Object getPreAuthenticatedPrincipal(HttpServletRequest request) {
        String principal = request.getHeader(PRINCIPAL_REQUEST_HEADER);
        if (principal == null && exceptionIfHeaderMissing) {
            throw new PreAuthenticatedCredentialsNotFoundException(PRINCIPAL_REQUEST_HEADER
                + " header not found in request.");
        }
        GrantedAuthority[] grantedAuthority = new GrantedAuthority[1];
        grantedAuthority[0] = new SimpleGrantedAuthority(principal);
        Collection<GrantedAuthority> authorities = new ArrayList<GrantedAuthority>();
        authorities.add(grantedAuthority[0]);
        return authorities;
    }

    @Override
    protected Object getPreAuthenticatedCredentials(HttpServletRequest request) {
         return "N/A";
    }

    public void setExceptionIfHeaderMissing(boolean exceptionIfHeaderMissing) {
        this.exceptionIfHeaderMissing = exceptionIfHeaderMissing;
    }

}

我的AuthenticationProvider實現:

public class AuthenticationProviderImpl implements AuthenticationProvider {

    @SuppressWarnings("unchecked")
    @Override
    public Authentication authenticate(Authentication authentication)
        throws AuthenticationException
    {
        Collection<? extends GrantedAuthority> authorities =
            (Collection<GrantedAuthority>)authentication.getPrincipal();
        PreAuthenticatedAuthenticationToken auth =
            new PreAuthenticatedAuthenticationToken(null, null, authorities);
        return auth;
    }

    @Override
    public boolean supports(Class<?> authentication) {
        return true;
    }

}

我的Java應用程序配置:

@Configuration
@ImportResource("classpath:spring-security.xml")
public class ApplicationConfiguration {

    @Bean
    public AbstractPreAuthenticatedProcessingFilter roleFilter() {
        RequestHeaderPreAuthenticatedProcessingFilterImpl filter =
            new RequestHeaderPreAuthenticatedProcessingFilterImpl();
        filter.setAuthenticationManager(authenticationManager());
        filter.setCheckForPrincipalChanges(true);
        filter.setExceptionIfHeaderMissing(false);
        return filter;
    }

    @Bean
    public AuthenticationProvider authenticationProvider() {
        return new AuthenticationProviderImpl();
    }

    @Bean(name = "authenticationManager")
    public AuthenticationManager authenticationManager() {
        List<AuthenticationProvider> authProviderList = new     ArrayList<AuthenticationProvider>();
        authProviderList.add(authenticationProvider());
        AuthenticationManager authenticationManager = new ProviderManager(authProviderList);
        return authenticationManager;
    }
}

我的spring-security.xml文件:

<?xml version="1.0" encoding="UTF-8"?>
<beans:beans xmlns="http://www.springframework.org/schema/security"
    xmlns:beans="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://www.springframework.org/schema/beans
    http://www.springframework.org/schema/beans/spring-beans-3.1.xsd
    http://www.springframework.org/schema/security
    http://www.springframework.org/schema/security/spring-security-3.1.xsd">

    <http use-expressions="true" auto-config="true" authentication-manager-ref="authenticationManager">
        <custom-filter position="PRE_AUTH_FILTER" ref="roleFilter" />
    <intercept-url pattern="/**" access="hasRole(ROLE_ADMIN)"/>
    </http>

</beans:beans>

這似乎確實很棘手,所以我很樂意看看其他建議。 因此,我將這個問題保留為開放性,不接受該答案。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM