云e办笔记(删减)
1JwtTokenUtils工具
package com.xxxx.server.config.security;
import io.jsonwebtoken.Claims;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.stereotype.Component;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
@Component
public class JwtTokenUtils {
private static final String CLAIM_KEY_USERNAME="sub";
private static final String CLAIM_KEY_CREATED="created";
@Value("${jwt.secret}")
private String secret;
@Value("${jwt.expiration}")
private Long expiration;
/**
* 创建token
* @param userDetails
* @return
*/
public String generateToken(UserDetails userDetails){
Map<String,Object> claims = new HashMap<>();
claims.put(CLAIM_KEY_USERNAME,userDetails.getUsername());
claims.put(CLAIM_KEY_CREATED,new Date());
return generateToken(claims);
}
private String generateToken(Map<String,Object> claims){
return Jwts.builder()
.setClaims(claims)
.setExpiration(generateExpirationDate())
.signWith(SignatureAlgorithm.ES512,secret)
.compact();
}
private Date generateExpirationDate() {
return new Date(System.currentTimeMillis()+expiration*1000);
}
/**
* 解析token,获取用户名
* @param token
* @return
*/
public String getUserNameToken(String token){
String username;
try {
Claims claims = getClaimsFormToken(token);
username = claims.getSubject();
}catch (Exception e){
e.printStackTrace();
username=null;
}
return username;
}
private Claims getClaimsFormToken(String token) {
Claims claims=null;
try{
claims=Jwts.parser()
.setSigningKey(secret)
.parseClaimsJws(token)
.getBody();
}catch (Exception e){
e.printStackTrace();
}
return claims;
}
/**
* 校驗是否真確
* @param token
* @param userDetails
* @return
*/
public boolean validateToken(String token,UserDetails userDetails){
String username = getUserNameToken(token);
return username.equals(userDetails.getUsername()) && !isTokenExpired(token);
}
/**
* 是否可以刷新时间
* @param token
* @return
*/
public boolean canRefresh(String token){
return !isTokenExpired(token);
}
/**
* 刷新token
* @param token
* @return
*/
public String refreshToken(String token){
Claims claims = getClaimsFormToken(token);
claims.put(CLAIM_KEY_CREATED,new Date());
return generateToken(claims);
}
private boolean isTokenExpired(String token) {
Date expireDate=getExpiredDateFromToken(token);
return expireDate.before(new Date());
}
private Date getExpiredDateFromToken(String token) {
Claims claims =getClaimsFormToken(token);
return claims.getExpiration();
}
}
2公共返回对象
package com.xxxx.server.pojo;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
@Data
@AllArgsConstructor
@NoArgsConstructor
public class RespBean {
private long code;
private String message;
private Object obj;
public static RespBean success(String message){
return new RespBean(200,message,null);
}
public static RespBean success(String message,Object obj){
return new RespBean(200,message,obj);
}
public static RespBean error(String message){
return new RespBean(500,message,null);
}
public static RespBean error(String message,Object obj){
return new RespBean(500,message,obj);
}
}
3Admin实现UserDetails
package com.xxxx.server.pojo;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import lombok.EqualsAndHashCode;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.userdetails.UserDetails;
import java.io.Serializable;
import java.util.Collection;
/**
* <p>
*
* </p>
*
* @author zhoubin
* @since 2021-09-09
*/
@Data
@EqualsAndHashCode(callSuper = false)
@TableName("t_admin")
@ApiModel(value="Admin对象", description="")
public class Admin implements Serializable, UserDetails {
private static final long serialVersionUID = 1L;
@ApiModelProperty(value = "id")
@TableId(value = "id", type = IdType.AUTO)
private Integer id;
@ApiModelProperty(value = "姓名")
private String name;
@ApiModelProperty(value = "手机号码")
private String phone;
@ApiModelProperty(value = "住宅电话")
private String telephone;
@ApiModelProperty(value = "联系地址")
private String address;
@ApiModelProperty(value = "是否启用")
private Boolean enabled;
@ApiModelProperty(value = "用户名")
private String username;
@ApiModelProperty(value = "密码")
private String password;
@ApiModelProperty(value = "用户头像")
private String userFace;
@ApiModelProperty(value = "备注")
private String remark;
@Override
public Collection<? extends GrantedAuthority> getAuthorities() {
return null;
}
@Override
public boolean isAccountNonExpired() {
return true;
}
@Override
public boolean isAccountNonLocked() {
return true;
}
@Override
public boolean isCredentialsNonExpired() {
return true;
}
@Override
public boolean isEnabled() {
return enabled;
}
}
4AdminLoginParam
package com.xxxx.server.pojo;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.experimental.Accessors;
@Data
@EqualsAndHashCode(callSuper = false)
@Accessors(chain = true)
@ApiModel(value ="AdminLogin对象",description = "")
public class AdminLoginParam {
@ApiModelProperty(value ="用户名",required =true)
private String username;
@ApiModelProperty(value ="密码",required = true)
private String password;
}
5AdminLoginController
package com.xxxx.server.controller;
import com.xxxx.server.pojo.Admin;
import com.xxxx.server.pojo.AdminLoginParam;
import com.xxxx.server.pojo.RespBean;
import com.xxxx.server.service.IAdminService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import javax.servlet.http.HttpServletRequest;
import java.security.Principal;
@RestController
@Api(tags = "LoginController")
public class LoginController {
@Autowired
private IAdminService adminService;
@ApiOperation(value="登录之后返回token")
@PostMapping("/login")
public RespBean login(AdminLoginParam adminLoginParam, HttpServletRequest httpServletRequest){
return adminService.login(adminLoginParam.getUsername(),adminLoginParam.getPassword(),httpServletRequest);
}
@ApiOperation("获取当前用户信息")
@PostMapping("/admin/info")
public Admin getAdminINfo(Principal principal){
if (null==principal){
return null;
}
String username = principal.getName();
Admin admin=adminService.getAdminByUserName(username);
admin.setPassword(null);
return admin;
}
@ApiOperation(value = "退出登录")
@RequestMapping("/logout")
public RespBean logout(){
return RespBean.success("注销成功!");
}
}
6SecurityConfig
package com.xxxx.server.config.security;
import com.xxxx.server.pojo.Admin;
import com.xxxx.server.service.IAdminService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.config.http.SessionCreationPolicy;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
@Configuration
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Autowired
private IAdminService adminService;
@Autowired
private RestAuthorizationEntryPoint restAuthorizationEntryPoint;
@Autowired
private ResstfulAccessDeniedHandler resstfulAccessDeniedHandler;
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.userDetailsService(userDetailsService()).passwordEncoder(passwordEncoder());
}
@Override
protected void configure(HttpSecurity http) throws Exception {
http.csrf().disable()
//基于token,不要session
.sessionManagement()
.sessionCreationPolicy(SessionCreationPolicy.STATELESS)/*
ALWAYS
总是创建HttpSession IF_REQUIRED
Spring Security只会在需要时创建一个HttpSession
NEVER
Spring Security不会创建HttpSession,但如果它已经存在,将可以使用HttpSession
STATELESS
Spring Security永远不会创建HttpSession,它不会使用HttpSession来获取SecurityContext
*/
.and()
.authorizeRequests()
.antMatchers("/login","/logout")
.permitAll()
.anyRequest()
.authenticated()
.and()
.headers()
.cacheControl();
//添加登录授权拦截器
http.addFilterBefore(jwtAuthencationTokenFilter(), UsernamePasswordAuthenticationFilter.class);
//自定义未授权和未登录结果返回
http.exceptionHandling()
//访问拒绝处理(权限不足)
.accessDeniedHandler(resstfulAccessDeniedHandler)
//重新认证入口点(未登录)
.authenticationEntryPoint(restAuthorizationEntryPoint);
}
@Override
@Bean
public UserDetailsService userDetailsService(){
return username->{
Admin admin = adminService.getAdminByUserName(username);
if (null!=admin){
return admin;
}
return null;
};
}
@Bean
public PasswordEncoder passwordEncoder(){
return new BCryptPasswordEncoder();
}
@Bean
public JwtAuthencationTokenFilter jwtAuthencationTokenFilter(){
return new JwtAuthencationTokenFilter();
}
}
7RestAuthorizationEntryPoint
package com.xxxx.server.config.security;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.xxxx.server.pojo.RespBean;
import org.springframework.context.annotation.Bean;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.web.AuthenticationEntryPoint;
import org.springframework.stereotype.Component;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;
/**
* 未登录时返回的结果
*/
@Component
public class RestAuthorizationEntryPoint implements AuthenticationEntryPoint {
@Override
public void commence(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, AuthenticationException e) throws IOException, ServletException {
httpServletResponse.setCharacterEncoding("UTF-8");
httpServletResponse.setContentType("application/json");
PrintWriter out =httpServletResponse.getWriter();
RespBean bean = RespBean.error("未登录");
bean.setCode(401);
out.write(new ObjectMapper().writeValueAsString(bean));
out.flush();
out.close();
}
}
8RestfulAccessDeniedHandle
package com.xxxx.server.config.security;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.xxxx.server.pojo.RespBean;
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;
import java.io.PrintWriter;
/**
* 权限不足返回的结果
*/
@Component
public class ResstfulAccessDeniedHandler implements AccessDeniedHandler {
@Override
public void handle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, AccessDeniedException e) throws IOException, ServletException {
httpServletResponse.setCharacterEncoding("UTF-8");
httpServletResponse.setContentType("application/json");
PrintWriter out = httpServletResponse.getWriter();
RespBean bean=RespBean.error("权限不足");
bean.setCode(403);
out.write(new ObjectMapper().writeValueAsString(bean));
out.flush();
out.close();
}
}
9ScurityConfig(增加Swagger2配置)
package com.xxxx.server.config.security;
import com.xxxx.server.pojo.Admin;
import com.xxxx.server.service.IAdminService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.builders.WebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.config.http.SessionCreationPolicy;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
@Configuration
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Autowired
private IAdminService adminService;
@Autowired
private RestAuthorizationEntryPoint restAuthorizationEntryPoint;
@Autowired
private ResstfulAccessDeniedHandler resstfulAccessDeniedHandler;
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.userDetailsService(userDetailsService()).passwordEncoder(passwordEncoder());
}
//允许基于选择匹配在资源级配置基于网络的安全性
@Override
protected void configure(HttpSecurity http) throws Exception {
http.csrf().disable()
//基于token,不要session
.sessionManagement()
.sessionCreationPolicy(SessionCreationPolicy.STATELESS)/*
ALWAYS
总是创建HttpSession IF_REQUIRED
Spring Security只会在需要时创建一个HttpSession
NEVER
Spring Security不会创建HttpSession,但如果它已经存在,将可以使用HttpSession
STATELESS
Spring Security永远不会创建HttpSession,它不会使用HttpSession来获取SecurityContext
*/
.and()
.authorizeRequests()
//websecurity已经配置
.antMatchers("/login","/logout")
.permitAll()
.anyRequest()
.authenticated()
.and()
.headers()
.cacheControl();
//添加登录授权拦截器
http.addFilterBefore(jwtAuthencationTokenFilter(), UsernamePasswordAuthenticationFilter.class);
//自定义未授权和未登录结果返回
http.exceptionHandling()
//访问拒绝处理(权限不足)
.accessDeniedHandler(resstfulAccessDeniedHandler)
//重新认证入口点(未登录)
.authenticationEntryPoint(restAuthorizationEntryPoint);
}
//用于影响全局安全性(配置资源,设置调试模式,通过实现自定义防火墙定义拒绝请求)的配置设置。
//
//一般用于配置全局的某些通用事物,例如静态资源等
@Override
public void configure(WebSecurity web) throws Exception {
web.ignoring()
.antMatchers("/login","/logout","/css/**",
"/js/**","/index.html","favicon.ico","/doc.html",
"/webjars/**","/swagger-resources/**","/v2/api-docs/**");
}
/**
* 拉姆达表达式
* @return
*/
@Override
@Bean
public UserDetailsService userDetailsService(){
return username->{
Admin admin = adminService.getAdminByUserName(username);
if (null!=admin){
return admin;
}
return null;
};
}
@Bean
public PasswordEncoder passwordEncoder(){
return new BCryptPasswordEncoder();
}
@Bean
public JwtAuthencationTokenFilter jwtAuthencationTokenFilter(){
return new JwtAuthencationTokenFilter();
}
}
10Swagger2Config
package com.xxxx.server.config;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import springfox.documentation.builders.ApiInfoBuilder;
import springfox.documentation.builders.PathSelectors;
import springfox.documentation.builders.RequestHandlerSelectors;
import springfox.documentation.service.*;
import springfox.documentation.spi.DocumentationType;
import springfox.documentation.spi.service.contexts.SecurityContext;
import springfox.documentation.spring.web.plugins.Docket;
import springfox.documentation.swagger2.annotations.EnableSwagger2;
import java.util.ArrayList;
import java.util.List;
@Configuration
@EnableSwagger2
public class Swagger2Config {
@Bean
public Docket createRestApi(){
//文档类型SWAGGER_2
return new Docket(DocumentationType.SWAGGER_2)
.apiInfo(apiInfo())
.select()
.apis(RequestHandlerSelectors.basePackage("com.xxxx.server.controller"))
.paths(PathSelectors.any())
.build()
.securityContexts(securityContexts())
.securitySchemes(securitySchemes());
}
private ApiInfo apiInfo(){
return new ApiInfoBuilder()
.title("云e办")
.description("云e办接口文档")
//内容
.contact(new Contact("xxxx","http:8081/doc.html","xxxx@xxxx.com"))
.version("1.0")
.build();
}
private List<ApiKey> securitySchemes() {
List<ApiKey> result = new ArrayList<>();
ApiKey apiKey = new ApiKey("Authorization", "Authorization", "Header");
result.add(apiKey);
return result;
}
private List<SecurityContext> securityContexts(){
//设置需要登录认证的的路径
List<SecurityContext> result = new ArrayList<>();
result.add(getContextByPath("/hello/.*"));
return result;
}
private SecurityContext getContextByPath(String pathRegex) {
return springfox.documentation.spi.service.contexts.SecurityContext.builder()
.securityReferences(defaultAuth())
.forPaths(PathSelectors.regex(pathRegex))
.build();
}
private List<SecurityReference> defaultAuth() {
List<SecurityReference> result = new ArrayList<>();
AuthorizationScope authorizationScope=new AuthorizationScope("global","accessEverything");
AuthorizationScope[] authorizationScopes=new AuthorizationScope[1];
authorizationScopes[0]=authorizationScope;
//下面要求要数组才这样
result.add(new SecurityReference("Authorization",authorizationScopes));
return result;
}
}
云e办笔记(删减)的更多相关文章
- 【山外笔记-云原生】《Docker+Kubernetes应用开发与快速上云》读书笔记-2020.04.25(六)
书名:Docker+Kubernetes应用开发与快速上云 作者:李文强 出版社:机械工业出版社 出版时间:2020-01 ISBN:9787111643012 [山外笔记-云原生]<Docke ...
- mysql部署到云主机的笔记
写了个程序,需要把数据库部署到云主机上 MySQL基于安全考虑root账户一般只能本地访问,但是在开发过程中可能需要打开root的远程访问权限 为了安全,新添加一个用户来进行远程登录 登录MYSQL: ...
- 阿里云服务器部署笔记一(python3、Flask、uWSGI、Nginx)
一.重置密码,并重启服务器 二.安全组配置>配置规则>添加安全组规则(为了能在本地ssh到实例) 配置如下: 此配置为允许任意公网IP登陆实例,注意windows与Linux系统端口范围不 ...
- 《Docker容器与容器云》读书笔记
云计算平台 云计算是一种资源的服务模式,该模式可以实现随时随地.便捷按需地从可配置计算资源共享池中获取所需资源(如网络.服务器.存储.应用及服务),资源能够快速供应并释放,大大减少了资源管理工作开销. ...
- 阿里云ubuntu环境笔记
安装jdk8 1.下载JDK 从官网下载jdk8 jdk-8u5-linux-x64.tar.gz 2.解压 $ tar -zxvf jdk-8u5-linux-x64.tar.gz 解压出来是一个j ...
- 【云迁移论文笔记】A Comparison of On-premise to Cloud Migration Approaches
A Comparison of On-premise to Cloud Migration Approaches Author Info: Claus Pahl senior lecturer at ...
- 【云迁移论文笔记】Cloud Migration Research:A Systematic Review
Cloud Migration Research:A Systematic Review Author Info: Pooyan Jamshidi PhD Postdoctoral Researche ...
- 阿里云服务器部署笔记二(python3、Flask、uWSGI、Nginx)
从git上把项目拉到服务器,项目可以在服务器上运行后,就只需要配置uwsgi和nginx了.它们的逻辑关系是:外部请求->nginx->uwsgi->项目实例. 一.配置uwsgi ...
- 阿里云serverless使用笔记
1.使用api网关服务,创建完api后,测试时,需要传“请求签名”,否则会报401 ‘Empty Signature’错误.相关文档<错误编码表,请求签名>.(错误信息放置与响应头的‘x- ...
随机推荐
- ApacheCN 深度学习译文集 20201229 更新
新增了七个教程: TensorFlow 和 Keras 应用开发入门 零.前言 一.神经网络和深度学习简介 二.模型架构 三.模型评估和优化 四.产品化 TensorFlow 图像深度学习实用指南 零 ...
- JavaCV的摄像头实战之五:推流
欢迎访问我的GitHub 这里分类和汇总了欣宸的全部原创(含配套源码):https://github.com/zq2599/blog_demos 本篇概览 本文是<JavaCV的摄像头实战> ...
- 如何高效地写 Form
工作少不了写"增删改查","增删改查"中的"增"和"改"都与 Form 有关,可以说:提升了 Form 的开发效率,就提 ...
- Linux-标准输入标准输出
标准输入(代码为0) 标准输出(代码为1) 标准错误输出(代码为2) 将标准输出重定向到一个文件 find /etc -name fileA >list 等同于 find /etc -name ...
- Kubernetes二进制(单/多节点)部署
Kubernetes二进制(单/多节点)部署 目录 Kubernetes二进制(单/多节点)部署 一.常见的K8S部署方式 1. Minikube 2. Kubeadmin 3. 二进制安装部署 4. ...
- jqGrid 修改单元格值或者替换图片及其他
var rowIds = jQuery("#list1").jqGrid('getDataIDs'); for (var k = 0; k < ...
- 帆软报表(finereport)table块钻取,返回记住table块位置
<1>首先table块加初始化事件,idex为参数,参数值为$tab_idexsetTimeout(function(){_g().getWidgetByName("tabpan ...
- 使用PHP利用phpmailer发送电子邮件
先来几句废话: phpMailer是一个非常强大的php发送邮件类,可以设定发送邮件地址.回复地址.邮件主题.html网页,上传附件,并且使用起来非常方便. phpMailer的特点: ...
- Spring Boot 自动配置(基本配置)
在关于Spring Boot的第一篇中就提到了其几大特性,其中关于Java配置简化属性注入在上一篇SpringBoot外部配置 - 池塘里洗澡的鸭子 - 博客园 (cnblogs.com)中已经介绍. ...
- pytest--配置用例执行顺序(pytest_ordering插件介绍)
前言 设置测试用例执行顺序: 默认情况下,pytest测试用例的执行顺序是按先外层后内层(目录下的文 件),再根据名称按ascii码值的顺序升序执行. 如果想自定义pytest测试用例的执行顺序,可以 ...