将Spring Security与SiteMinder集成

时间:2014-04-09 03:08:22

标签: java spring spring-mvc spring-security siteminder

如何将Spring Security与SiteMinder集成以接收用户和角色?

我有一个Spring Security'in-memory'的项目设置,我想使用它来转换它以接受带有User和Roles的SiteMinder标题。如果SiteMinder将发送用户角色(ROLE_READ,ROLE_WRITE)并具有服务层授予访问权限。如何转换内存以使用SiteMinder?

内存中用户角色

内存中的用户和角色列表

<authentication-manager>
    <authentication-provider>
        <user-service>
            <user name="test" password="test" authorities="ROLE_READ" />
            <user name="admin" password="admin" authorities="ROLE_READ,ROLE_WRITE" />
        </user-service>
    </authentication-provider>
</authentication-manager>

服务层保护

此处服务方法受特定角色保护

<beans:bean id="testService" class="com.stackoverflow.test" scope="request">
    <security:intercept-methods>
        <security:protect access="ROLE_WRITE" method="do*"/>
        <security:protect access="ROLE_READ" method="find*"/>
    </security:intercept-methods>
</beans:bean>

此来源(Spring Security Java Config for Siteminder)看起来很有前景,但它始终被赋予角色RoleEmployee。

1 个答案:

答案 0 :(得分:4)

SiteMinder的Spring Security仅用于接收用户。但是,要接收角色,您需要创建扩展身份验证过程。这将使用角色对用户进行身份验证。

root-security.xml

<beans:bean id="userDetailsService" class="test.sm.SiteMinderUserDetailsService"/>

<beans:bean id="preauthAuthProvider" class="org.springframework.security.web.authentication.preauth.PreAuthenticatedAuthenticationProvider">
    <beans:property name="preAuthenticatedUserDetailsService">
        <beans:bean id="userDetailsServiceWrapper" class="org.springframework.security.core.userdetails.UserDetailsByNameServiceWrapper">
            <beans:property name="userDetailsService" ref="userDetailsService" />
        </beans:bean>
    </beans:property>
</beans:bean>

<beans:bean id="siteminderFilter" class="test.sm.SiteMinderFilter">
    <beans:property name="principalRequestHeader" value="SM_USER" />
    <beans:property name="rolesRequestHeader" value="SM_ROLE" />
    <beans:property name="rolesDelimiter" value="," />
    <beans:property name="authenticationManager" ref="authenticationManager" />
</beans:bean>

<authentication-manager alias="authenticationManager">
    <authentication-provider ref="preauthAuthProvider" />
</authentication-manager>

SiteMinderUserDetailsS​​ervice

public class SiteMinderUserDetailsService extends PreAuthenticatedGrantedAuthoritiesUserDetailsService implements
        UserDetailsService {

    @Override
    public UserDetails loadUserByUsername(String arg0) throws UsernameNotFoundException {
        SiteMinderUserDetails userDetails = new SiteMinderUserDetails();
        userDetails.setUsername(arg0);      
        return userDetails;
    }

    @Override
    protected UserDetails createuserDetails(Authentication token, Collection<? extends GrantedAuthority> authorities) {
        return super.createuserDetails(token, authorities);
    }
}

SiteMinderUserDetails

public class SiteMinderUserDetails implements UserDetails {
    // implement all methods
}

SiteMinderFilter

public class SiteMinderFilter extends RequestHeaderAuthenticationFilter {

    private String rolesRequestHeader;
    private String rolesDelimiter;

    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException, NullPointerException {

        String roles = (String)  ((HttpServletRequest)request).getHeader(getRolesRequestHeader());
        String[] rolesArray = roles.split(rolesDelimiter);

        Collection<SimpleGrantedAuthority> auth = new ArrayList<SimpleGrantedAuthority>();
        for (String s : rolesArray) {               
            auth.add(new SimpleGrantedAuthority(s));
        }

        SiteMinderUserDetails userDetails = new SiteMinderUserDetails();
        userDetails.setUsername((String) super.getPreAuthenticatedPrincipal(((HttpServletRequest)request)));
        userDetails.setAuthorities(auth);

        AuthenticationImpl authentication = new AuthenticationImpl();
        authentication.setAuthenticated(true);
        authentication.setAuthorities(auth);
        authentication.setPrincipal(userDetails);
        authentication.setCredentials(super.getPreAuthenticatedCredentials(((HttpServletRequest)request)));
        SecurityContextHolder.getContext().setAuthentication(authentication);

        super.doFilter(request, response, chain);
    }

    public SiteMinderFilter() {
        super();        
    }

    @Override
    public void setPrincipalRequestHeader(String principalRequestHeader) {
        super.setPrincipalRequestHeader(principalRequestHeader);
    }

    public void setRolesRequestHeader(String rolesRequestHeader) {
        this.rolesRequestHeader = rolesRequestHeader;
    }

    public String getRolesRequestHeader() {
        return rolesRequestHeader;
    }


    public void setRolesDelimiter(String rolesDelimiter) {
        this.rolesDelimiter = rolesDelimiter;
    }

    public String getRolesDelimiter() {
        return rolesDelimiter;
    }
}

AuthenticationImpl

public class AuthenticationImpl implements Authentication {
    // implement all methods
}