package me.zhengjie.core.security;import com.fasterxml.jackson.annotation.JsonIgnore;import lombok.AllArgsConstructor;import lombok.Getter;import org.springframework.security.core.GrantedAuthority;import org.springframework.security.core.userdetails.UserDetails;import java.sql.Timestamp;import java.util.*;/** * @author jie * @date 2018-11-23 */@Getter@AllArgsConstructorpublic class JwtUser implements UserDetails { @JsonIgnore private final Long id; private final String username; @JsonIgnore private final String password; private final String avatar; private final String email; @JsonIgnore private final Collection<? extends GrantedAuthority> authorities; private final boolean enabled; private Timestamp createTime; @JsonIgnore private final Date lastPasswordResetDate; @JsonIgnore @Override public boolean isAccountNonExpired() { return true; } @JsonIgnore @Override public boolean isAccountNonLocked() { return true; } @JsonIgnore @Override public boolean isCredentialsNonExpired() { return true; } @JsonIgnore @Override public String getPassword() { return password; } @Override public boolean isEnabled() { return enabled; } /** * 在我们保存权限的时候加上了前缀ROLE_,因此在这里需要处理下数据 * @return */ public Collection getRoles() { Set<String> roles = new LinkedHashSet<>(); for (GrantedAuthority authority : authorities) { roles.add(authority.getAuthority().substring(5)); } return roles; }}
package me.zhengjie.core.security;import org.springframework.security.core.AuthenticationException;import org.springframework.security.web.AuthenticationEntryPoint;import org.springframework.stereotype.Component;import javax.servlet.http.HttpServletRequest;import javax.servlet.http.HttpServletResponse;import java.io.IOException;import java.io.Serializable;@Componentpublic classJwtAuthenticationEntryPoint implements AuthenticationEntryPoint, Serializable { private static final long serialVersionUID = -8970718410437077606L; @Override public void commence(HttpServletRequest request, HttpServletResponse response, AuthenticationException authException) throws IOException { /** * 当用户尝试访问安全的REST资源而不提供任何凭据时,将调用此方法发送401 响应 */ response.sendError(HttpServletResponse.SC_UNAUTHORIZED, authException==null?"Unauthorized":authException.getMessage()); }}
package me.zhengjie.core.security;import org.springframework.security.core.AuthenticationException;import org.springframework.security.web.AuthenticationEntryPoint;import org.springframework.stereotype.Component;import javax.servlet.http.HttpServletRequest;import javax.servlet.http.HttpServletResponse;import java.io.IOException;import java.io.Serializable;@Componentpublic classJwtAuthenticationEntryPoint implements AuthenticationEntryPoint, Serializable { private static final long serialVersionUID = -8970718410437077606L; @Override public void commence(HttpServletRequest request, HttpServletResponse response, AuthenticationException authException) throws IOException { /** * 当用户尝试访问安全的REST资源而不提供任何凭据时,将调用此方法发送401 响应 */ response.sendError(HttpServletResponse.SC_UNAUTHORIZED, authException==null?"Unauthorized":authException.getMessage()); }}
package me.zhengjie.core.security;import io.jsonwebtoken.ExpiredJwtException;import me.zhengjie.core.utils.JwtTokenUtil;import org.slf4j.Logger;import org.slf4j.LoggerFactory;import org.springframework.beans.factory.annotation.Qualifier;import org.springframework.beans.factory.annotation.Value;import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;import org.springframework.security.core.context.SecurityContextHolder;import org.springframework.security.core.userdetails.UserDetails;import org.springframework.security.core.userdetails.UserDetailsService;import org.springframework.security.web.authentication.WebAuthenticationDetailsSource;import org.springframework.stereotype.Component;import org.springframework.web.filter.OncePerRequestFilter;import javax.servlet.FilterChain;import javax.servlet.ServletException;import javax.servlet.http.HttpServletRequest;import javax.servlet.http.HttpServletResponse;import java.io.IOException;@Componentpublic class JwtAuthorizationTokenFilter extends OncePerRequestFilter { private final Logger logger = LoggerFactory.getLogger(this.getClass()); private final UserDetailsService userDetailsService; private final JwtTokenUtil jwtTokenUtil; private final String tokenHeader; public JwtAuthorizationTokenFilter(@Qualifier("jwtUserDetailsService") UserDetailsService userDetailsService, JwtTokenUtil jwtTokenUtil, @Value("${jwt.header}") String tokenHeader) { this.userDetailsService = userDetailsService; this.jwtTokenUtil = jwtTokenUtil; this.tokenHeader = tokenHeader; } @Override protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain chain) throws ServletException, IOException { logger.debug("processing authentication for '{}'", request.getRequestURL()); final String requestHeader = request.getHeader(this.tokenHeader); String username = null; String authToken = null; if (requestHeader != null && requestHeader.startsWith("Bearer ")) { authToken = requestHeader.substring(7); try { username = jwtTokenUtil.getUsernameFromToken(authToken); } catch (ExpiredJwtException e) { logger.error(e.getMessage()); } } logger.debug("checking authentication for user '{}'", username); if (username != null && SecurityContextHolder.getContext().getAuthentication() == null) { logger.debug("security context was null, so authorizating user"); // It is not compelling necessary to load the use details from the database. You could also store the information // in the token and read it from it. It's up to you ;) UserDetails userDetails = this.userDetailsService.loadUserByUsername(username); // For simple validation it is completely sufficient to just check the token integrity. You don't have to call // the database compellingly. Again it's up to you ;) if (jwtTokenUtil.validateToken(authToken, userDetails)) { UsernamePasswordAuthenticationToken authentication = new UsernamePasswordAuthenticationToken(userDetails, null, userDetails.getAuthorities()); authentication.setDetails(new WebAuthenticationDetailsSource().buildDetails(request)); logger.info("authorizated user '{}', setting security context", username); SecurityContextHolder.getContext().setAuthentication(authentication); } } chain.doFilter(request, response); }}
package me.zhengjie.core.service;import me.zhengjie.common.exception.EntityNotFoundException;import me.zhengjie.common.utils.ValidationUtil;import me.zhengjie.core.security.JwtUser;import me.zhengjie.system.domain.Permission;import me.zhengjie.system.domain.Role;import me.zhengjie.system.domain.User;import me.zhengjie.system.repository.PermissionRepository;import me.zhengjie.system.repository.UserRepository;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.cache.annotation.CacheConfig;import org.springframework.cache.annotation.Cacheable;import org.springframework.security.core.GrantedAuthority;import org.springframework.security.core.authority.SimpleGrantedAuthority;import org.springframework.security.core.userdetails.UserDetails;import org.springframework.security.core.userdetails.UserDetailsService;import org.springframework.stereotype.Service;import org.springframework.transaction.annotation.Propagation;import org.springframework.transaction.annotation.Transactional;import java.util.ArrayList;import java.util.HashSet;import java.util.List;import java.util.Set;import java.util.stream.Collectors;/** * @author jie * @date 2018-11-22 */@Service@Transactional(propagation = Propagation.SUPPORTS, readOnly = true, rollbackFor = Exception.class)public class JwtUserDetailsService implements UserDetailsService { @Autowired private UserRepository userRepository; @Autowired private PermissionRepository permissionRepository; @Override public UserDetails loadUserByUsername(String username){ User user = null; if(ValidationUtil.isEmail(username)){ user = userRepository.findByEmail(username); } else { user = userRepository.findByUsername(username); } if (user == null) { throw new EntityNotFoundException(User.class, "name", username); } else { return create(user); } } public UserDetails create(User user) { return new JwtUser( user.getId(), user.getUsername(), user.getPassword(), user.getAvatar(), user.getEmail(), mapToGrantedAuthorities(user.getRoles(),permissionRepository), user.getEnabled(), user.getCreateTime(), user.getLastPasswordResetTime() ); } private static List<GrantedAuthority> mapToGrantedAuthorities(Set<Role> roles,PermissionRepository permissionRepository) { Set<Permission> permissions = new HashSet<>(); for (Role role : roles) { Set<Role> roleSet = new HashSet<>(); roleSet.add(role); permissions.addAll(permissionRepository.findByRoles(roleSet)); } return permissions.stream() .map(permission -> new SimpleGrantedAuthority("ROLE_" permission.getName())) .collect(Collectors.toList()); }}
package me.zhengjie.core.service;import me.zhengjie.common.exception.EntityNotFoundException;import me.zhengjie.common.utils.ValidationUtil;import me.zhengjie.core.security.JwtUser;import me.zhengjie.system.domain.Permission;import me.zhengjie.system.domain.Role;import me.zhengjie.system.domain.User;import me.zhengjie.system.repository.PermissionRepository;import me.zhengjie.system.repository.UserRepository;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.cache.annotation.CacheConfig;import org.springframework.cache.annotation.Cacheable;import org.springframework.security.core.GrantedAuthority;import org.springframework.security.core.authority.SimpleGrantedAuthority;import org.springframework.security.core.userdetails.UserDetails;import org.springframework.security.core.userdetails.UserDetailsService;import org.springframework.stereotype.Service;import org.springframework.transaction.annotation.Propagation;import org.springframework.transaction.annotation.Transactional;import java.util.ArrayList;import java.util.HashSet;import java.util.List;import java.util.Set;import java.util.stream.Collectors;/** * @author jie * @date 2018-11-22 */@Service@Transactional(propagation = Propagation.SUPPORTS, readOnly = true, rollbackFor = Exception.class)public class JwtUserDetailsService implements UserDetailsService { @Autowired private UserRepository userRepository; @Autowired private PermissionRepository permissionRepository; @Override public UserDetails loadUserByUsername(String username){ User user = null; if(ValidationUtil.isEmail(username)){ user = userRepository.findByEmail(username); } else { user = userRepository.findByUsername(username); } if (user == null) { throw new EntityNotFoundException(User.class, "name", username); } else { return create(user); } } public UserDetails create(User user) { return new JwtUser( user.getId(), user.getUsername(), user.getPassword(), user.getAvatar(), user.getEmail(), mapToGrantedAuthorities(user.getRoles(),permissionRepository), user.getEnabled(), user.getCreateTime(), user.getLastPasswordResetTime() ); } private static List<GrantedAuthority> mapToGrantedAuthorities(Set<Role> roles,PermissionRepository permissionRepository) { Set<Permission> permissions = new HashSet<>(); for (Role role : roles) { Set<Role> roleSet = new HashSet<>(); roleSet.add(role); permissions.addAll(permissionRepository.findByRoles(roleSet)); } return permissions.stream() .map(permission -> new SimpleGrantedAuthority("ROLE_" permission.getName())) .collect(Collectors.toList()); }}
来源:https://www.icode9.com/content-4-340251.html
联系客服