Java tutorial
/** * Copyright (c)2010-2011 Enterprise Website Content Management System(EWCMS), All rights reserved. * EWCMS PROPRIETARY/CONFIDENTIAL. Use is subject to license terms. * http://www.ewcms.com */ package com.sshdemo.common.security.manage.service; import java.util.Date; import java.util.HashSet; import java.util.Set; import org.apache.commons.lang.StringUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.dao.DataAccessException; import org.springframework.security.access.AccessDeniedException; import org.springframework.security.authentication.AuthenticationManager; import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; import org.springframework.security.authentication.dao.SaltSource; import org.springframework.security.authentication.encoding.PasswordEncoder; import org.springframework.security.authentication.encoding.PlaintextPasswordEncoder; import org.springframework.security.core.Authentication; import org.springframework.security.core.AuthenticationException; import org.springframework.security.core.GrantedAuthority; import org.springframework.security.core.authority.GrantedAuthorityImpl; import org.springframework.security.core.context.SecurityContextHolder; import org.springframework.security.core.userdetails.UserDetails; import org.springframework.security.core.userdetails.UsernameNotFoundException; import org.springframework.stereotype.Service; import org.springframework.util.Assert; import com.sshdemo.common.security.manage.model.Authority; import com.sshdemo.common.security.manage.model.Group; import com.sshdemo.common.security.manage.model.User; import com.sshdemo.common.security.manage.model.UserInfo; @Service public class UserService extends AbstractService implements UserServiceable { private static final Logger logger = LoggerFactory.getLogger(UserService.class); private String defaultPassword = "666666"; @Autowired(required = false) private AuthenticationManager authenticationManager; @Autowired(required = false) private PasswordEncoder passwordEncoder = new PlaintextPasswordEncoder(); @Autowired(required = false) private SaltSource saltSource; @Override public String addUser(final String username, final String password, final boolean enabled, final Date accountStart, final Date accountEnd, final UserInfo userInfo) throws UserServiceException { if (accountStart != null && accountEnd != null) { Assert.isTrue(accountEnd.getTime() > accountStart.getTime(), "account date start > end"); } if (hasUsername(username)) { throw new UserServiceException( messages.getMessage("UserService.usernameExist", "username already exist")); } User user = new User(username, enabled, accountStart, accountEnd); UserInfo info = (userInfo != null ? userInfo : new UserInfo()); info.setUsername(username); if (info.getName() == null) { info.setName(username); } user.setUserInfo(info); //?? String newPassword = StringUtils.isBlank(password) ? defaultPassword : password; user.setPassword(newPassword); //UserDetails password? UserDetails userDetails = createUserDetails(user); user.setPassword(passwordEncoder(userDetails, newPassword)); userDao.persist(user); return username; } /** * * * ? * * @param username ?? * @return * @throws UserServiceException */ private User getExistUser(final String username) throws UserServiceException { User user = userDao.get(username); if (user == null) { throw new UserServiceException(messages.getMessage("GroupService.groupNotFound", new Object[] { username }, "Can't found " + username + " username")); } return user; } @Override public String updateUser(final String username, final boolean enabled, final Date accountStart, final Date accountEnd, final UserInfo userInfo) throws UserServiceException { if (accountStart != null && accountEnd != null) { Assert.isTrue(accountEnd.getTime() > accountStart.getTime(), "account date start > end"); } User user = getExistUser(username); user.setEnabled(enabled); user.setAccountStart(accountStart); user.setAccountEnd(accountEnd); user.getUserInfo().setBirthday(userInfo.getBirthday()); user.getUserInfo().setEmail(userInfo.getEmail()); user.getUserInfo().setIdentification(userInfo.getIdentification()); user.getUserInfo().setMphone(userInfo.getMphone()); user.getUserInfo().setName(userInfo.getName()); user.getUserInfo().setPhone(userInfo.getPhone()); userDao.persist(user); return username; } @Override public User getUser(final String username) { return userDao.get(username); } @Override public void removeUser(final String username) { userDao.removeByPK(username); userCache.removeUserFromCache(username); } @Override public void activeUser(final String username) throws UserServiceException { User user = getExistUser(username); user.setEnabled(true); } @Override public void inactiveUser(final String username) throws UserServiceException { User user = getExistUser(username); user.setEnabled(false); userDao.persist(user); removeExpiredUserByUsername(username); } @Override public Set<Authority> addAuthoritiesToUser(String username, Set<String> names) throws UserServiceException { User user = getExistUser(username); Set<Authority> newAuths = new HashSet<Authority>(); for (String name : names) { Authority newAuth = getAuthorityByName(name); if (!user.getAuthorities().contains(newAuth)) { newAuths.add(newAuth); } } user.getAuthorities().addAll(newAuths); userDao.persist(user); removeExpiredUserByUsername(username); return newAuths; } @Override public void removeAuthoritiesInUser(String username, Set<String> names) throws UserServiceException { User user = getExistUser(username); Set<Authority> auths = new HashSet<Authority>(); for (Authority auth : user.getAuthorities()) { if (!names.contains(auth.getName())) { auths.add(auth); } } user.setAuthorities(auths); userDao.persist(user); removeExpiredUserByUsername(username); } @Override public Set<Group> addGroupsToUser(String username, Set<String> names) { User user = getExistUser(username); Set<Group> newGroups = new HashSet<Group>(); for (String name : names) { Group newGroup = getGroupByName(name); if (!user.getGroups().contains(newGroup)) { newGroups.add(newGroup); } } user.getGroups().addAll(newGroups); userDao.persist(user); removeExpiredUserByUsername(username); return newGroups; } @Override public void removeGroupsInUser(String username, Set<String> names) { User user = getExistUser(username); Set<Group> groups = new HashSet<Group>(); for (Group group : user.getGroups()) { if (!names.contains(group.getName())) { groups.add(group); } } user.setGroups(groups); userDao.persist(user); removeExpiredUserByUsername(username); } @Override public UserInfo getCurrentUserInfo() throws AuthenticationException { Authentication currentUser = SecurityContextHolder.getContext().getAuthentication(); if (currentUser == null) { throw new AccessDeniedException( "Can't change user info as no Authentication object found in context for current user."); } final String username = currentUser.getName(); User user = userDao.get(username); return user == null ? null : user.getUserInfo(); } @Override public void updateUserInfo(final UserInfo userInfo) throws AuthenticationException { Authentication currentUser = SecurityContextHolder.getContext().getAuthentication(); if (currentUser == null) { throw new AccessDeniedException( "Can't change user info as no Authentication object found in context for current user."); } final String username = currentUser.getName(); User user = userDao.get(username); if (user == null) { if (logger.isDebugEnabled()) { logger.debug("{} user is null", username); } return; } user.getUserInfo().setBirthday(userInfo.getBirthday()); user.getUserInfo().setEmail(userInfo.getEmail()); user.getUserInfo().setIdentification(userInfo.getIdentification()); user.getUserInfo().setMphone(userInfo.getMphone()); user.getUserInfo().setName(userInfo.getName()); user.getUserInfo().setPhone(userInfo.getPhone()); userDao.persist(user); } @Override public void changePassword(final String oldPassword, final String newPassword) throws AuthenticationException { Authentication currentUser = SecurityContextHolder.getContext().getAuthentication(); if (currentUser == null) { throw new AccessDeniedException( "Can't change password as no Authentication object found in context for current user."); } final String username = currentUser.getName(); if (this.authenticationManager != null) { if (logger.isDebugEnabled()) { logger.debug("Reauthenticating user '{}' for password change request.", username); } authenticationManager.authenticate(new UsernamePasswordAuthenticationToken(username, oldPassword)); } else { if (logger.isDebugEnabled()) { logger.debug("No authentication manage set.Password won't be re-checked"); } } if (logger.isDebugEnabled()) { logger.debug("Changing password for user {}'", username); } UserDetails userDetails = loadUserByUsername(username); String encoder = passwordEncoder(userDetails, newPassword); userDao.updatePassword(username, encoder); SecurityContextHolder.getContext().setAuthentication(createNewAuthentication(userDetails, encoder)); userCache.removeUserFromCache(username); } protected String passwordEncoder(UserDetails userDetails, String password) { Object salt = (saltSource == null ? null : saltSource.getSalt(userDetails)); return passwordEncoder.encodePassword(password, salt); } protected Authentication createNewAuthentication(UserDetails userDetails, String newPassword) { UsernamePasswordAuthenticationToken newAuthentication = new UsernamePasswordAuthenticationToken(userDetails, userDetails.getPassword(), userDetails.getAuthorities()); newAuthentication.setDetails(userDetails); return newAuthentication; } @Override public void initPassword(final String username, final String password) throws AuthenticationException { UserDetails userDetails = this.loadUserByUsername(username); String encoder = passwordEncoder(userDetails, password); userDao.updatePassword(username, encoder); userCache.removeUserFromCache(username); } @Override public boolean hasUsername(String username) { User user = userDao.get(username); return user != null; } @Override public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException, DataAccessException { UserDetails userDetails = userCache.getUserFromCache(username); if (userDetails != null) { if (logger.isDebugEnabled()) { logger.debug("userDetails has cache"); } return userDetails; } if (logger.isDebugEnabled()) { logger.debug("userDetails has not cache"); } User user = userDao.get(username); if (user == null) { throw new UsernameNotFoundException("not fonund " + username); } userDetails = createUserDetails(user); userCache.putUserInCache(userDetails); return userDetails; } /** * PO User?Spring Security UserDetails * * @param user * @return UserDetails */ private UserDetails createUserDetails(final User user) { Assert.notNull(user, "user is null"); Set<GrantedAuthority> authorities = new HashSet<GrantedAuthority>(); Set<Authority> auths = user.getAuthorities(); if (auths != null) { if (logger.isDebugEnabled()) { logger.debug("loadding user authorities"); } for (Authority auth : auths) { authorities.add(new GrantedAuthorityImpl(auth.getName())); } } Set<Group> groups = user.getGroups(); if (groups != null) { for (Group group : groups) { if (logger.isDebugEnabled()) { logger.debug("lodding {} of group authorities", group.getName()); } authorities.addAll(groupAuthorities(group)); } } return new org.springframework.security.core.userdetails.User(user.getUsername(), user.getPassword(), user.isEnabled(), noExpired(user.getAccountStart(), user.getAccountEnd()), true, true, authorities); } /** * * * start=nullend=null,? * * @param start * @param end ? * @return true ? false */ protected boolean noExpired(final Date start, final Date end) { if (start == null && end == null) { return true; } boolean nonExpired = true; long now = System.currentTimeMillis(); if (start != null) { nonExpired = nonExpired && start.getTime() <= now; } if (end != null) { nonExpired = nonExpired && end.getTime() >= now; } return nonExpired; } /** * ?? * * ????ACL * * @param group * @return ?? */ protected Set<GrantedAuthority> groupAuthorities(final Group group) { Set<GrantedAuthority> authorities = new HashSet<GrantedAuthority>(); Set<Authority> auths = group.getAuthorities(); if (auths != null) { for (Authority auth : auths) { authorities.add(new GrantedAuthorityImpl(auth.getName())); } } authorities.add(new GrantedAuthorityImpl(group.getName())); return authorities; } public void setDefaultPassword(String defaultPassword) { this.defaultPassword = defaultPassword; } @Override public String getDefaultPassword() { return this.defaultPassword; } public void setAuthenticationManager(AuthenticationManager authenticationManager) { this.authenticationManager = authenticationManager; } public void setPasswordEncoder(PasswordEncoder passwordEncoder) { this.passwordEncoder = passwordEncoder; } public void setSaltSource(SaltSource saltSource) { this.saltSource = saltSource; } }