云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- ...
随机推荐
- openstack horizon 学习(3) DataTable
上一篇中粗略的讲了下openstack中horizon的dashboard和panel的添加,本打算在这章中对有关于pluggable settings中的配置做详细的总结,然放弃了这念头.原因是搞懂 ...
- 分布式系统及CAP理论
一.集中式系统 在学习分布式之前,先了解一下与之相对应的集中式系统是什么样的. 集中式系统用一句话概括就是:一个主机带多个终端.终端没有数据处理能力,仅负责数据的录入和输出.而运算.存储等全部在主机上 ...
- keystore文件
[-] keystore操作 运行时签名文件路径debug 生成签名文件打包时使用 获取MD5和SH1 修改keystore文件密码 修改keystore文件别名 修改keystore文件别名的密码 ...
- js null和{}区别
{}是一个不完全空的对象,因为他的原型链上还有Object呢,而null就是完全空的对象,啥也没有,原型链也没有,所以null instanceof Object === false;[]就更不用说了 ...
- LaunchScreen&LaunchImage
优先级:LaunchScreen > LaunchImage 在xcode配置了,不起作用 1.清空xcode缓存 2.直接删掉程序 重新运行 如果是通过LaunchImage设置启动界面,那么 ...
- 什么是rest?restful?
百度百科解释: rest:REST即表述性状态传递(英文:Representational State Transfer,简称REST)是Roy Fielding博士在2000年他的博士论文中提出来的 ...
- node 解决存储xss风险报告
1. 安装 xss模块 npm install xss 2.在 Node.js 中使用 const xss = require("xss"); // 在项目的接口里面添加 let ...
- Linux爱情故事之如何以不一样的姿势(ssh)进入她的心
文章目录 1.ssh是谁,为什么要进入她的心 2.如何正确的扒拉ssh 2.1.ssh的常用参数 2.2.您配钥匙吗?(ssh生成公钥或者秘钥) 2.3.我要单向畅通无阻的进入你的心(ssh-copy ...
- 力扣算法经典第一题——两数之和(Java两种方式实现)
一.题目 难度:简单 给定一个整数数组 nums 和一个整数目标值 target,请你在该数组中找出 和为目标值 target 的那 两个 整数, 并返回它们的数组下标. 你可以假设每种输入只会对应一 ...
- 使用Flask开发简单接口
作为测试人员,在工作或者学习的过程中,有时会没有可以调用的现成的接口,导致我们的代码没法调试跑通的情况. 这时,我们使用python中的web框架Flask就可以很方便的编写简单的接口,用于调用或调试 ...