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 extends GrantedAuthority> getAuthorities() {
List list = new ArrayList();
for(Role role : roles){
list.add(new GrantedAuthorityImpl(role.getName()));
}
return list;
}
}
Spring Security的配置 没贴出来。