Spring Security 3.1 配置笔记二

Spring Security 3.1 配置笔记二

上篇博文贴了项目中Spring MVC 和Spring的配置文件,导入相应的包,完善拦截器和代码就可以把Web工程跑起来。

这次是Spring Security的配置:

如果<form-login/>这样配置,不设置属性,那么在验证时会跳转到SS3的默认登录页面,通过配置可以使用自定义的登录页面,包括登录表单的表单项。

从SS3的配置文件可以知道,我们还需要自己的过滤器实现securityCoreFilter、认证管理authenticationManager、访问决策accessDecisionManager、资源管理securityMetadataSource,

这些通过一些网友的研究可以直接拿来使用:

securityCoreFilter:

/**
 * 权限检查拦截器
 * @author HideHai
 *
 */
public class SecurityCoreInterceptor extends AbstractSecurityInterceptor implements Filter{

	private  FilterInvocationSecurityMetadataSource securityMetadataSource;
	public static final String SPRING_SECURITY_SESSION_ID = "ACEGI_SECURITY_CONTEXT";


	public void setSecurityMetadataSource(
			FilterInvocationSecurityMetadataSource securityMetadataSource) {
		this.securityMetadataSource = securityMetadataSource;
	}
	@Override
	public void doFilter(ServletRequest request, ServletResponse response,
			FilterChain chain) throws IOException, ServletException {
		HttpSession session =((HttpServletRequest)request).getSession(false);
		if(session != null){
			Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
			authentication = (Authentication) session.getAttribute(SecurityCoreInterceptor.SPRING_SECURITY_SESSION_ID);
			SecurityContextHolder.getContext().setAuthentication(authentication);
		}
		FilterInvocation filterInvocation = new FilterInvocation(request, response, chain);
		invoke(filterInvocation);
		if(session != null && SecurityContextHolder.getContext().getAuthentication() != null){
			session.setAttribute(SecurityCoreInterceptor.SPRING_SECURITY_SESSION_ID, SecurityContextHolder.getContext().getAuthentication());
		}
	}
	@Override
	public void destroy() {
		// TODO Auto-generated method stub

	}
	@Override
	public void init(FilterConfig arg0) throws ServletException {
		// TODO Auto-generated method stub

	}
	@Override
	public Class getSecureObjectClass() {
		// TODO Auto-generated method stub
		return FilterInvocation.class;
	}
	@Override
	public SecurityMetadataSource obtainSecurityMetadataSource() {
		// TODO Auto-generated method stub
		return this.securityMetadataSource;
	}

	/**
	 * 执行拦截器前检查权限
	 * @param filterInvocation
	 * @throws IOException
	 * @throws ServletException
	 */
	private void invoke(FilterInvocation filterInvocation) throws IOException, ServletException{
		InterceptorStatusToken token = super.beforeInvocation(filterInvocation);
		try {
			filterInvocation.getChain().doFilter(filterInvocation.getRequest(),filterInvocation.getResponse());
		}finally{
			super.afterInvocation(token,null);
		}
	}

authenticationManager:

@Service("userService")
public class UserServiceImpl implements UserService,UserDetailsService {
	
	@Autowired
	private BaseDao baseDao;

	@Override
	public User get(Integer id) {
		User user = (User) baseDao.get(User.class, id);
		return user;
	}

	@Override
	public User findUserByUserName(String username) {
		return (User)baseDao.getByProperty(User.class, "username", username);
	}

	@Override
	public UserDetails loadUserByUsername(String username)
			throws UsernameNotFoundException {
		User user = findUserByUserName(username);
		return user;
	}

}

accessDecisionManager:


@Component("myAccessDecisionManager")
public class MyAccessDecisionManager implements AccessDecisionManager{
	private Logger log = LoggerFactory.getLogger(Thread.class);
	@Override
	public void decide(Authentication authentication, Object object,
			Collection configAttributes) throws AccessDeniedException,
			InsufficientAuthenticationException {
		if(configAttributes == null ){
			return;
		}
		Iterator iterator = configAttributes.iterator();
		while(iterator.hasNext()){
			ConfigAttribute attribute = iterator.next();
			String needRole = ((SecurityConfig)attribute).getAttribute();
			for(GrantedAuthority grantedAuthority : authentication.getAuthorities()){
				if(needRole.equals(grantedAuthority.getAuthority())){
					return;
				}
			}
		}
		log.warn("Permissions Denied! 没有权限!");
		throw new AccessDeniedException("Permissions Denied! 没有权限!");
	}

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

	@Override
	public boolean supports(Class arg0) {
		return true;
	}

}

实现了Detail接口的用户实体:

@Entity
@Table(name="pre_users")
public class User implements Serializable,UserDetails{

	/**
	 * 
	 */
	private static final long serialVersionUID = 1187792569617956220L;
	@Id
	@GeneratedValue(strategy=GenerationType.AUTO)
	private Integer id;
	
	@Column(name = "username")
	private String username;
	
	@Column(name = "password")
	private String password;
	
	@Column(name = "enable")
	private boolean enable;
	
	@ManyToMany(targetEntity=com.winxuan.channel.model.member.Role.class,cascade={CascadeType.MERGE,CascadeType.PERSIST},fetch=FetchType.EAGER)   
    @JoinTable(name="pre_user_2_role",joinColumns={@JoinColumn(name="user_id")},inverseJoinColumns={@JoinColumn(name="role_id")}) 
	private Set roles;
	
	
	public Integer getId() {
		return id;
	}
	public void setId(Integer id) {
		this.id = id;
	}
	public String getUsername() {
		return username;
	}
	public void setUsername(String username) {
		this.username = username;
	}
	public String getPassword() {
		return password;
	}
	public void setPassword(String password) {
		this.password = password;
	}
	public boolean isEnable() {
		return enable;
	}
	public void setEnable(boolean enable) {
		this.enable = enable;
	}
	
	
	public Set getRoles() {
		return roles;
	}
	public void setRoles(Set roles) {
		this.roles = roles;
	}
	@Override
	public boolean isAccountNonExpired() {
		return true;
	}
	@Override
	public boolean isAccountNonLocked() {
		return true;
	}
	@Override
	public boolean isCredentialsNonExpired() {
		return true;
	}
	@Override
	public boolean isEnabled() {
		return this.isEnable();
	}

	@Override
	public Collection getAuthorities() {
		List list = new ArrayList();
		for(Role role : roles){
			list.add(new GrantedAuthorityImpl(role.getName()));
		}
		return list;
	}
}

Spring Security 3.1 配置笔记二》有1条留言

留下回复