`
jlcon
  • 浏览: 169996 次
  • 性别: Icon_minigender_1
  • 来自: 重庆
社区版块
存档分类
最新评论

Spring Security 3 证书登录

    博客分类:
  • Java
阅读更多

默认情况下ss3的<x509>标签只会取证书主题作为验证条件,如果想要自己指定证书的某一部分作为验证条件需要手动实现X509PrincipalExtractor接口:

import org.springframework.security.web.authentication.preauth.x509.X509PrincipalExtractor;

public class MyX509PrincipalExtractor implements X509PrincipalExtractor{

	Logger logger = LoggerFactory.getLogger(this.getClass());
	
	/**
	 * 获取证书序列号
	 * @param cert x509证书对象
	 */
	@Override
	public Object extractPrincipal(X509Certificate cert) {
		String serialNumber = cert.getSerialNumber().toString(16);//取证书序列号作为判断条件
		return serialNumber;
	}

}

 实现用户描述接口:

public class MyUserAuthority implements UserDetails{
……
}

 

载入用户信息:

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.userdetails.AuthenticationUserDetailsService;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UsernameNotFoundException;

/**
 * 
 * Company: xxx公司 <br>
 *
 * Description:  用户信息载入服务
 *
 * <br>Copyright: Copyright (c) 2010 - 2015
 *
 * <br>Author: JLCON 
 * <br>Created:2010-9-17
 *
 * <br>Modified:2010-9-17
 *
 * <br>version:V1.0
 */
public class MyUserDetailService implements AuthenticationUserDetailsService{

	Logger logger = LoggerFactory.getLogger(this.getClass());
	

    //载入用户信息
	@Autowired
	private UserAuthorityInfo userinfo;
	

	/**
	 * 用户信息载入
	 * @param token 认证token
	 */
	@Override
	public UserDetails loadUserDetails(Authentication token)
			throws UsernameNotFoundException {//这里得到的就是刚才返回的证书ID
		return userinfo.getUserDetails(token.getPrincipal().toString());
	}

}

 通过URL获取该URL具有的访问属性:

public class X509securityMetadataSource implements FilterInvocationSecurityMetadataSource{

import org.springframework.security.web.access.intercept.FilterInvocationSecurityMetadataSource;
…………

	@Override
	public Collection<ConfigAttribute> getAttributes(Object object)
			throws IllegalArgumentException {
		String url = ((FilterInvocation)object).getRequestUrl();

		………………

		return list;
	}

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

}

 认证访问控制器:

public class X509AccessDecisionManager implements AccessDecisionManager{

	Logger logger = LoggerFactory.getLogger(this.getClass());
	
	/**
	 * 决定是否有权限访问资源
	 * @param authentication 登录用户权限信息
	 * @param object 访问的资源对象
	 * @param configAttributes 资源对象具有的配置属性
	 * @exception AccessDeniedException 访问被拒绝
	 */
	@Override
	public void decide(Authentication authentication, Object object,
			Collection<ConfigAttribute> configAttributes)
			throws AccessDeniedException, InsufficientAuthenticationException {
		FilterInvocation filterInvocation = (FilterInvocation)object;
		for(ConfigAttribute configAttribute:configAttributes)
		{
			for(GrantedAuthority grantedAuthority:authentication.getAuthorities())
			{
				if(configAttribute.getAttribute().equalsIgnoreCase(grantedAuthority.getAuthority()))
				{
					logger.debug("访问success! - {}",filterInvocation.getFullRequestUrl());
					return;
				}
			}
		}
		logger.debug("无权访问! - {}",filterInvocation.getFullRequestUrl());

		throw new AccessDeniedException("无权限!");
	}

	@Override
	public boolean supports(ConfigAttribute attribute) {
		return true;
	}

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

}

  最后上配置:

<?xml version="1.0" encoding="UTF-8"?>
<b:beans xmlns:b="http://www.springframework.org/schema/beans"
    xmlns="http://www.springframework.org/schema/security"
    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.0.xsd
    http://www.springframework.org/schema/security http://www.springframework.org/schema/security/spring-security-3.0.xsd">

	<http access-denied-page="/accessdenied.jsp">
		<custom-filter position="X509_FILTER" ref="x509Filter"/>
		<custom-filter ref="x509Intercepter" before="FILTER_SECURITY_INTERCEPTOR"/>
		<intercept-url pattern="/*" requires-channel="https"/>
		<port-mappings>
			<port-mapping http="8080" https="8443"/>
		</port-mappings>
		<form-login/>
	</http>
	
	<b:bean id="preAuthenticatedProcessingFilterEntryPoint" class="org.springframework.security.web.authentication.preauth.PreAuthenticatedProcessingFilterEntryPoint">
	</b:bean>
	
	<b:bean id="x509Filter" class="org.springframework.security.web.authentication.preauth.x509.X509AuthenticationFilter">
		<b:property name="authenticationManager" ref="authenticationmanager"></b:property>
		<b:property name="principalExtractor">
			<b:bean class=".....MyX509PrincipalExtractor"></b:bean>
		</b:property>
	</b:bean>
	
	<b:bean id="x509Intercepter" class="org.springframework.security.web.access.intercept.FilterSecurityInterceptor">
		<b:property name="authenticationManager" ref="authenticationmanager"></b:property>
		<b:property name="securityMetadataSource" ref="x509securityMetadataSource"></b:property>
		<b:property name="accessDecisionManager" ref="x509AccessDecisionManager"></b:property>
	</b:bean>
	
	<b:bean id="x509securityMetadataSource" class="....X509securityMetadataSource"></b:bean>
	<b:bean id="x509AccessDecisionManager" class="....X509AccessDecisionManager"></b:bean>
	
	<authentication-manager alias="authenticationmanager" >
		<authentication-provider ref="x509provider">
		</authentication-provider>
	</authentication-manager>
	
	<b:bean id="x509provider" class="org.springframework.security.web.authentication.preauth.PreAuthenticatedAuthenticationProvider">
		<b:property name="preAuthenticatedUserDetailsService" ref="UserDetailsService">
		</b:property>
		<b:property name="throwExceptionWhenTokenRejected" value="true"></b:property>
	</b:bean>
	
	<b:bean id="loggerListener" class="org.springframework.security.authentication.event.LoggerListener"/>
	
	<b:bean id="UserDetailsService" class="....MyUserDetailService"></b:bean>
	
	<b:bean id="UserAuthorityInfo" class="....UserAuthorityInfoImp"></b:bean>
	
</b:beans>

 web.xml

。。。。。
<filter>
        <filter-name>springSecurityFilterChain</filter-name>
        <filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
    </filter>

    <filter-mapping>
      <filter-name>springSecurityFilterChain</filter-name>
      <url-pattern>/manager/*</url-pattern>
    </filter-mapping>

。。。。。

补充UserAuthorityInfo代码:

 

ABCUserAuthority:

public class ABCUserAuthority implements UserDetails{

	private static final long serialVersionUID = -6394802605626145354L;
	。。。。。
}

 

UserAuthorityInfo:

 

@Repository
public class UserAuthorityInfoImp implements UserAuthorityInfo {

	Logger logger = LoggerFactory.getLogger(this.getClass());
	@Autowired
	private SessionFactory sf;

        public UserDetails getUserDetails(String username)
	{
              ABCUserAuthority user = new ABCUserAuthority();
              return user;
         }
}
 
分享到:
评论
5 楼 jlcon 2013-08-29  
jackyrong 写道
请教下,看到了提取证书序列号了,但如何比较保存在DB中的序列号是否和当前用户登录用的证书序列号一致呢?这个是spring security自己完成的么?还有,我原来的是用户名和密码登录页面,那么现在改成一个按钮,这个按钮点后,其action事件应该如何编写?谢谢

第一个问题,获取的证书ID和数据库的比对在MyUserDetailService类的方法中实现。
第二个问题,页面获取证书序列号,到Action中获取序列号调用登录方法,将证书序列号传递给ss完成登录。
4 楼 jackyrong 2013-08-22  
请教下,看到了提取证书序列号了,但如何比较保存在DB中的序列号是否和当前用户登录用的证书序列号一致呢?这个是spring security自己完成的么?还有,我原来的是用户名和密码登录页面,那么现在改成一个按钮,这个按钮点后,其action事件应该如何编写?谢谢
3 楼 jlcon 2012-10-30  
已更新,添加UserAuthorityInfo说明
2 楼 wise_wei 2012-10-15  
遇到楼上一样的问题。。。 求解
1 楼 guangliruan0208 2012-02-28  
<b:bean id="UserAuthorityInfo" class="....UserAuthorityInfoImp"></b:bean>该类没有源代码呀~~可以说明下认证流程么~~

相关推荐

Global site tag (gtag.js) - Google Analytics