From da20e10fc20fa4e2d11bf41c2bda8fad22744381 Mon Sep 17 00:00:00 2001 From: zhh Date: Tue, 24 Apr 2018 13:24:53 +0800 Subject: [PATCH] =?UTF-8?q?=E9=83=A8=E5=88=86=E9=97=AE=E9=A2=98=E4=BF=AE?= =?UTF-8?q?=E5=A4=8D?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 2 +- .../JwtAuthenticationTokenFilter.java | 1 - .../component/RestfulAccessDeniedHandler.java | 26 +++++++++ .../com/macro/mall/config/SecurityConfig.java | 55 ++++++++++--------- .../mall/controller/UmsAdminController.java | 2 +- .../java/com/macro/mall/dto/CommonResult.java | 17 ++++++ .../service/impl/UmsAdminServiceImpl.java | 21 +++++-- 7 files changed, 91 insertions(+), 33 deletions(-) create mode 100644 mall-admin/src/main/java/com/macro/mall/component/RestfulAccessDeniedHandler.java diff --git a/README.md b/README.md index f62b93b..8db49ed 100644 --- a/README.md +++ b/README.md @@ -32,7 +32,7 @@ SpringAOP通用日志处理 | ✔ SpringAOP通用验证失败结果返回 | ✔ CommonResult对通用返回结果进行封装 | ✔ SpringSecurity登录改为Restful形式 | -JWT登录、注册、获取token | +JWT登录、注册、获取token | ✔ ### 功能完善 diff --git a/mall-admin/src/main/java/com/macro/mall/component/JwtAuthenticationTokenFilter.java b/mall-admin/src/main/java/com/macro/mall/component/JwtAuthenticationTokenFilter.java index ac36fcf..d0c1cd8 100644 --- a/mall-admin/src/main/java/com/macro/mall/component/JwtAuthenticationTokenFilter.java +++ b/mall-admin/src/main/java/com/macro/mall/component/JwtAuthenticationTokenFilter.java @@ -22,7 +22,6 @@ import java.io.IOException; /** * JWT登录授权过滤器 */ -@Component public class JwtAuthenticationTokenFilter extends OncePerRequestFilter { private static final Logger LOGGER = LoggerFactory.getLogger(JwtAuthenticationTokenFilter.class); @Autowired diff --git a/mall-admin/src/main/java/com/macro/mall/component/RestfulAccessDeniedHandler.java b/mall-admin/src/main/java/com/macro/mall/component/RestfulAccessDeniedHandler.java new file mode 100644 index 0000000..d2b0aa6 --- /dev/null +++ b/mall-admin/src/main/java/com/macro/mall/component/RestfulAccessDeniedHandler.java @@ -0,0 +1,26 @@ +package com.macro.mall.component; + +import com.macro.mall.dto.CommonResult; +import com.macro.mall.util.JsonUtil; +import org.springframework.security.access.AccessDeniedException; +import org.springframework.security.web.access.AccessDeniedHandler; +import org.springframework.stereotype.Component; + +import javax.servlet.ServletException; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import java.io.IOException; + +/** + * 用于Rest请求是返回自定义错误信息 + */ +@Component +public class RestfulAccessDeniedHandler implements AccessDeniedHandler{ + @Override + public void handle(HttpServletRequest request, + HttpServletResponse response, + AccessDeniedException e) throws IOException, ServletException { + response.setStatus(HttpServletResponse.SC_FORBIDDEN); + response.getWriter().println(JsonUtil.objectToJson(new CommonResult().authFailed(e.getMessage()))); + } +} diff --git a/mall-admin/src/main/java/com/macro/mall/config/SecurityConfig.java b/mall-admin/src/main/java/com/macro/mall/config/SecurityConfig.java index ecafd0e..d5a979b 100644 --- a/mall-admin/src/main/java/com/macro/mall/config/SecurityConfig.java +++ b/mall-admin/src/main/java/com/macro/mall/config/SecurityConfig.java @@ -2,6 +2,7 @@ package com.macro.mall.config; import com.macro.mall.bo.AdminUserDetails; import com.macro.mall.component.JwtAuthenticationTokenFilter; +import com.macro.mall.component.RestfulAccessDeniedHandler; import com.macro.mall.model.UmsAdmin; import com.macro.mall.service.UmsAdminService; import org.springframework.beans.factory.annotation.Autowired; @@ -18,6 +19,7 @@ import org.springframework.security.config.http.SessionCreationPolicy; import org.springframework.security.core.userdetails.UserDetails; import org.springframework.security.core.userdetails.UserDetailsService; import org.springframework.security.core.userdetails.UsernameNotFoundException; +import org.springframework.security.web.access.AccessDeniedHandler; import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter; @@ -32,31 +34,33 @@ public class SecurityConfig extends WebSecurityConfigurerAdapter { @Override protected void configure(HttpSecurity httpSecurity) throws Exception { - httpSecurity.csrf()// 由于使用的是JWT,我们这里不需要csrf - .disable() - .sessionManagement()// 基于token,所以不需要session - .sessionCreationPolicy(SessionCreationPolicy.STATELESS) - .and() - .authorizeRequests() - .antMatchers(HttpMethod.GET, // 允许对于网站静态资源的无授权访问 - "/", - "/*.html", - "/favicon.ico", - "/**/*.html", - "/**/*.css", - "/**/*.js", - "/swagger-resources/**", - "/v2/api-docs/**" - ) - .permitAll() - .antMatchers("/admin/**")// 对于获取token的rest api要允许匿名访问 - .permitAll() - .anyRequest()// 除上面外的所有请求全部需要鉴权认证 - .authenticated(); + httpSecurity.csrf()// 由于使用的是JWT,我们这里不需要csrf + .disable() + .sessionManagement()// 基于token,所以不需要session + .sessionCreationPolicy(SessionCreationPolicy.STATELESS) + .and() + .authorizeRequests() + .antMatchers(HttpMethod.GET, // 允许对于网站静态资源的无授权访问 + "/", + "/*.html", + "/favicon.ico", + "/**/*.html", + "/**/*.css", + "/**/*.js", + "/swagger-resources/**", + "/v2/api-docs/**" + ) + .permitAll() + .antMatchers("/admin/**")// 对于获取token的rest api要允许匿名访问 + .permitAll() + .antMatchers("/**")//测试时全部运行访问 + .permitAll() + .anyRequest()// 除上面外的所有请求全部需要鉴权认证 + .authenticated(); // 禁用缓存 - httpSecurity.headers().cacheControl(); + httpSecurity.headers().cacheControl(); // 添加JWT filter - httpSecurity.addFilterBefore(jwtAuthenticationTokenFilter(), UsernamePasswordAuthenticationFilter.class); + httpSecurity.addFilterBefore(jwtAuthenticationTokenFilter(), UsernamePasswordAuthenticationFilter.class); } @Override @@ -66,7 +70,7 @@ public class SecurityConfig extends WebSecurityConfigurerAdapter { } @Bean - public PasswordEncoder passwordEncoder(){ + public PasswordEncoder passwordEncoder() { return new Md5PasswordEncoder(); } @@ -77,7 +81,7 @@ public class SecurityConfig extends WebSecurityConfigurerAdapter { @Override public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException { UmsAdmin admin = adminService.getAdminByUsername(username); - if(admin!=null){ + if (admin != null) { return new AdminUserDetails(admin); } throw new UsernameNotFoundException("用户名或密码错误"); @@ -89,4 +93,5 @@ public class SecurityConfig extends WebSecurityConfigurerAdapter { public JwtAuthenticationTokenFilter jwtAuthenticationTokenFilter(){ return new JwtAuthenticationTokenFilter(); } + } diff --git a/mall-admin/src/main/java/com/macro/mall/controller/UmsAdminController.java b/mall-admin/src/main/java/com/macro/mall/controller/UmsAdminController.java index 74d6adf..43c4bb7 100644 --- a/mall-admin/src/main/java/com/macro/mall/controller/UmsAdminController.java +++ b/mall-admin/src/main/java/com/macro/mall/controller/UmsAdminController.java @@ -47,7 +47,7 @@ public class UmsAdminController { public Object login(@RequestBody UmsAdminLoginParam umsAdminLoginParam, BindingResult result) { String token = adminService.login(umsAdminLoginParam.getUsername(), umsAdminLoginParam.getPassword()); if (token == null) { - new CommonResult().failed(); + return new CommonResult().validateFailed("用户名或密码错误"); } return new CommonResult().success(token); } diff --git a/mall-admin/src/main/java/com/macro/mall/dto/CommonResult.java b/mall-admin/src/main/java/com/macro/mall/dto/CommonResult.java index 277eeff..cf90610 100644 --- a/mall-admin/src/main/java/com/macro/mall/dto/CommonResult.java +++ b/mall-admin/src/main/java/com/macro/mall/dto/CommonResult.java @@ -12,9 +12,14 @@ import java.util.Map; * 通用返回对象 */ public class CommonResult { + //操作成功 public static final int SUCCESS = 0; + //操作失败 public static final int FAILED = 1; + //参数校验失败 public static final int VALIDATE_FAILED = 2; + //认证失败 + public static final int AUTHENTICATE_FAILED = 3; private int code; private String message; private Object data; @@ -68,6 +73,18 @@ public class CommonResult { return this; } + /** + * 参数验证失败使用 + * + * @param message 错误信息 + */ + public CommonResult authFailed(String message) { + this.code = AUTHENTICATE_FAILED; + this.message = "认证失败"; + this.data = message; + return this; + } + /** * 参数验证失败使用 * @param result 错误信息 diff --git a/mall-admin/src/main/java/com/macro/mall/service/impl/UmsAdminServiceImpl.java b/mall-admin/src/main/java/com/macro/mall/service/impl/UmsAdminServiceImpl.java index 8b93ad7..38cd87a 100644 --- a/mall-admin/src/main/java/com/macro/mall/service/impl/UmsAdminServiceImpl.java +++ b/mall-admin/src/main/java/com/macro/mall/service/impl/UmsAdminServiceImpl.java @@ -6,6 +6,8 @@ import com.macro.mall.model.UmsAdmin; import com.macro.mall.model.UmsAdminExample; import com.macro.mall.service.UmsAdminService; import com.macro.mall.util.JwtTokenUtil; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import org.springframework.beans.BeanUtils; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; @@ -13,6 +15,7 @@ import org.springframework.security.authentication.AuthenticationManager; import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; import org.springframework.security.authentication.encoding.PasswordEncoder; import org.springframework.security.core.Authentication; +import org.springframework.security.core.AuthenticationException; import org.springframework.security.core.context.SecurityContextHolder; import org.springframework.security.core.userdetails.UserDetails; import org.springframework.security.core.userdetails.UserDetailsService; @@ -25,6 +28,7 @@ import java.util.List; */ @Service public class UmsAdminServiceImpl implements UmsAdminService{ + private static final Logger LOGGER = LoggerFactory.getLogger(UmsAdminServiceImpl.class); @Autowired private UmsAdminMapper adminMapper; @Autowired @@ -69,11 +73,18 @@ public class UmsAdminServiceImpl implements UmsAdminService{ @Override public String login(String username, String password) { - UsernamePasswordAuthenticationToken authenticationToken = new UsernamePasswordAuthenticationToken(username,password); - Authentication authentication = authenticationManager.authenticate(authenticationToken); - SecurityContextHolder.getContext().setAuthentication(authentication); - UserDetails userDetails = userDetailsService.loadUserByUsername(username); - return jwtTokenUtil.generateToken(userDetails); + String token = null; + //密码需要客户端加密后传递 + UsernamePasswordAuthenticationToken authenticationToken = new UsernamePasswordAuthenticationToken(username,passwordEncoder.encodePassword(password,null)); + try { + Authentication authentication = authenticationManager.authenticate(authenticationToken); + SecurityContextHolder.getContext().setAuthentication(authentication); + UserDetails userDetails = userDetailsService.loadUserByUsername(username); + token = jwtTokenUtil.generateToken(userDetails); + } catch (AuthenticationException e) { + LOGGER.warn("登录异常:{}",e.getMessage()); + } + return token; } @Override