扩展springsecurity的User类

扩展User类 实现更丰富的User属性
为了安装UserInfo没有提供属性set方法,赋值都在构造器中完成

首先实现UserDetails接口
package com.snda.swp.account.po;

import java.io.Serializable;
import java.util.Collection;
import java.util.Collections;
import java.util.Comparator;
import java.util.Set;
import java.util.SortedSet;
import java.util.TreeSet;

import org.springframework.security.core.CredentialsContainer;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.util.Assert;

//不可变类
public class UserInfo implements UserDetails, CredentialsContainer {

 private static final long serialVersionUID = 5997839307263494359L;

 // ~ Instance fields
 // ================================================================================================
 private String password;

 private String name;// 用户的中文姓名

 private String email;// 用户的邮箱地址

 private final String username;

 private final Set<GrantedAuthority> authorities;

 private final boolean accountNonExpired;

 private final boolean accountNonLocked;

 private final boolean credentialsNonExpired;

 private final boolean enabled;

 // ~ Constructors
 // ===================================================================================================
 public UserInfo(String password, String name, String email,
   final String username,
   final Collection<? extends GrantedAuthority> authorities,
   final boolean accountNonExpired, final boolean accountNonLocked,
   final boolean credentialsNonExpired, final boolean enabled) {
  if (username == null || "".equals(username) || password == null)
   throw new IllegalArgumentException(
     "Cannot pass null or empty values to constructor");
  this.password = password;
  this.name = name;
  this.email = email;
  this.username = username;
  this.accountNonExpired = accountNonExpired;
  this.accountNonLocked = accountNonLocked;
  this.credentialsNonExpired = credentialsNonExpired;
  this.enabled = enabled;
  this.authorities = Collections
    .unmodifiableSet(sortAuthorities(authorities));
 }

 // ~ Methods
 // ========================================================================================================
 public Collection<GrantedAuthority> getAuthorities() {
  return authorities;
 }

 public String getPassword() {
  return password;
 }

 public String getUsername() {
  return username;
 }

 public String getEmail() {
  return email;
 }

 public String getName() {
  return name;
 }

 public boolean isAccountNonExpired() {
  return accountNonExpired;
 }

 public boolean isAccountNonLocked() {
  return accountNonLocked;
 }

 public boolean isCredentialsNonExpired() {
  return credentialsNonExpired;
 }

 public boolean isEnabled() {
  return enabled;
 }

 public void eraseCredentials() {
  password = null;
 }

 private static SortedSet<GrantedAuthority> sortAuthorities(
   Collection<? extends GrantedAuthority> authorities) {
  Assert.notNull(authorities,
    "Cannot pass a null GrantedAuthority collection");
  // Ensure array iteration order is predictable (as per
  // UserDetails.getAuthorities() contract and SEC-717)
  SortedSet<GrantedAuthority> sortedAuthorities = new TreeSet<GrantedAuthority>(
    new AuthorityComparator());

  for (GrantedAuthority grantedAuthority : authorities) {
   Assert.notNull(grantedAuthority,
     "GrantedAuthority list cannot contain any null elements");
   sortedAuthorities.add(grantedAuthority);
  }

  return sortedAuthorities;
 }

 private static class AuthorityComparator implements
   Comparator<GrantedAuthority>, Serializable {
  public int compare(GrantedAuthority g1, GrantedAuthority g2) {
   // Neither should ever be null as each entry is checked before
   // adding it to the set.
   // If the authority is null, it is a custom authority and should
   // precede others.
   if (g2.getAuthority() == null) {
    return -1;
   }

   if (g1.getAuthority() == null) {
    return 1;
   }

   return g1.getAuthority().compareTo(g2.getAuthority());
  }
 }

 @Override
 public boolean equals(Object rhs) {
  if (rhs instanceof UserInfo)
   return username.equals(((UserInfo) rhs).username);
  return false;
 }

 @Override
 public int hashCode() {
  return username.hashCode();
 }

 @Override
 public String toString() {
  StringBuilder sb = new StringBuilder();
  sb.append(super.toString()).append(": ");
  sb.append("Username: ").append(this.username).append("; ");
  sb.append("Password: [PROTECTED]; ");
  sb.append("Enabled: ").append(this.enabled).append("; ");
  sb.append("AccountNonExpired: ").append(this.accountNonExpired).append(
    "; ");
  sb.append("credentialsNonExpired: ").append(this.credentialsNonExpired)
    .append("; ");
  sb.append("AccountNonLocked: ").append(this.accountNonLocked).append(
    "; ");

  if (!authorities.isEmpty()) {
   sb.append("Granted Authorities: ");

   boolean first = true;
   for (GrantedAuthority auth : authorities) {
    if (!first) {
     sb.append(",");
    }
    first = false;

    sb.append(auth);
   }
  } else {
   sb.append("Not granted any authorities");
  }
  return sb.toString();
 }
}


实现UserDetailsService接口
package com.snda.swp.account.service;

import java.util.Set;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.dao.DataAccessException;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.GrantedAuthorityImpl;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.transaction.annotation.Transactional;
import com.google.common.collect.Sets;
import com.snda.swp.account.po.Authority;
import com.snda.swp.account.po.Role;
import com.snda.swp.account.po.User;
import com.snda.swp.account.po.UserInfo;

/**
 * 实现SpringSecurity的UserDetailsService接口,实现获取用户Detail信息的回调函数.
 *
 * @author calvin
 */
@Transactional(readOnly = true)
public class UserDetailsServiceImpl implements UserDetailsService {

 private AccountManager accountManager;

 /**
  * 获取用户Details信息的回调函数.
  */
 public UserDetails loadUserByUsername(String username)
   throws UsernameNotFoundException, DataAccessException {
  User user = accountManager.findUserByLoginName(username);
  if (user == null) {
   throw new UsernameNotFoundException("用户" + username + " 不存在");
  }

  Set<GrantedAuthority> grantedAuths = obtainGrantedAuthorities(user);

  // -- mini-web示例中无以下属性, 暂时全部设为true. --//
  boolean enabled = true;
  boolean accountNonExpired = true;
  boolean credentialsNonExpired = true;
  boolean accountNonLocked = true;

  UserInfo userdetails = new UserInfo(user.getPassword(), user.getName(),
    user.getEmail(), user.getLoginName(), grantedAuths,
    accountNonExpired, accountNonLocked, credentialsNonExpired,
    enabled);

  return userdetails;
 }

 /**
  * 获得用户所有角色的权限集合.
  */
 private Set<GrantedAuthority> obtainGrantedAuthorities(User user) {
  Set<GrantedAuthority> authSet = Sets.newHashSet();
  for (Role role : user.getRoleList()) {
   for (Authority authority : role.getAuthorityList()) {
    authSet.add(new GrantedAuthorityImpl(authority
      .getPrefixedName()));
   }
  }
  return authSet;
 }

 @Autowired
 public void setAccountManager(AccountManager accountManager) {
  this.accountManager = accountManager;
 }
}


重写SpringSecurityUtils类
package com.snda.swp.account.service;

import java.util.Collection;

import javax.servlet.http.HttpServletRequest;

import org.springframework.security.core.Authentication;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.context.SecurityContext;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.web.authentication.WebAuthenticationDetails;
import org.springframework.security.web.authentication.preauth.PreAuthenticatedAuthenticationToken;

import com.snda.swp.account.po.UserInfo;

/**
 * SpringSecurity的工具类.
 *
 * 注意. 本类只支持SpringSecurity 3.0.x.
 *
 * @author calvin
 */
public class SpringSecurityUtils {
 /**
  * 取得当前用户, 返回值为UserInfo类或其子类, 如果当前用户未登录则返回null.
  */
 @SuppressWarnings("unchecked")
 public static <T extends UserInfo> T getCurrentUser() {
  Authentication authentication = getAuthentication();

  if (authentication == null) {
   return null;
  }

  Object principal = authentication.getPrincipal();
  if (!(principal instanceof UserInfo)) {
   return null;
  }

  return (T) principal;
 }

 /**
  * 取得当前用户的登录名, 如果当前用户未登录则返回空字符串.
  */
 public static String getCurrentUserName() {
  Authentication authentication = getAuthentication();

  if (authentication == null || authentication.getPrincipal() == null) {
   return "";
  }

  return authentication.getName();
 }
 
 /**
  * 取得当前用户的真实姓名, 如果当前用户未登录则返回空字符串.
  */
 public static String getCurrentName() {
  return getCurrentUser().getName();
 }

 /**
  * 取得当前用户登录IP, 如果当前用户未登录则返回空字符串.
  */
 public static String getCurrentUserIp() {
  Authentication authentication = getAuthentication();

  if (authentication == null) {
   return "";
  }

  Object details = authentication.getDetails();
  if (!(details instanceof WebAuthenticationDetails)) {
   return "";
  }

  WebAuthenticationDetails webDetails = (WebAuthenticationDetails) details;
  return webDetails.getRemoteAddress();
 }

 /**
  * 判断用户是否拥有角色, 如果用户拥有参数中的任意一个角色则返回true.
  */
 public static boolean hasAnyRole(String... roles) {
  Authentication authentication = getAuthentication();

  if (authentication == null) {
   return false;
  }

  Collection<GrantedAuthority> grantedAuthorityList = authentication
    .getAuthorities();
  for (String role : roles) {
   for (GrantedAuthority authority : grantedAuthorityList) {
    if (role.equals(authority.getAuthority())) {
     return true;
    }
   }
  }

  return false;
 }

 /**
  * 将UserDetails保存到Security Context.
  *
  * @param userDetails
  *            已初始化好的用户信息.
  * @param request
  *            用于获取用户IP地址信息,可为Null.
  */
 public static void saveUserDetailsToContext(UserDetails userDetails,
   HttpServletRequest request) {
  PreAuthenticatedAuthenticationToken authentication = new PreAuthenticatedAuthenticationToken(
    userDetails, userDetails.getPassword(), userDetails
      .getAuthorities());

  if (request != null) {
   authentication.setDetails(new WebAuthenticationDetails(request));
  }

  SecurityContextHolder.getContext().setAuthentication(authentication);
 }

 /**
  * 取得Authentication, 如当前SecurityContext为空时返回null.
  */
 private static Authentication getAuthentication() {
  SecurityContext context = SecurityContextHolder.getContext();

  if (context == null) {
   return null;
  }

  return context.getAuthentication();
 }
}


applicationContext-security.xml中的配置
<!-- 认证配置, 使用userDetailsService提供的用户信息 -->
	<s:authentication-manager alias="authenticationManager">
		<s:authentication-provider user-service-ref="userDetailsService">
			<s:password-encoder hash="plaintext" />
		</s:authentication-provider>
	</s:authentication-manager>

	<!-- 项目实现的用户查询服务 -->
	<bean id="userDetailsService" class="org.springside.examples.miniweb.service.account.UserDetailsServiceImpl" />
</beans>

你可能感兴趣的:(DAO,Web,servlet,Google,Security)