1. 程式人生 > 實用技巧 >深度學習與PyTorch | 深度學習的介紹 | 01

深度學習與PyTorch | 深度學習的介紹 | 01

spring boot + spring Security + redis + token 爬坡

分為幾個部分 spring boot 基本配置 controller介面部分 安全校驗部分(包括session或者自定義token的形式) redis的token存放於取出 , 在資料庫取使用者資訊

spring boot 基本配置

pom和啟動類

https://www.cnblogs.com/funkboy/p/12889708.html pom的jar版本要一一對應,不要產生spring衝突

application.yml 和 properties 配置

https://www.cnblogs.com/luzhanshi/p/10597641.html

like this

實現檢驗思路

Security 部分

兩種思路,

第一種

一種是spring Security只負責校驗 ,生成和儲存token的部分放在controller裡

這種情況只需要

WebSecurityConfigurer extends WebSecurityConfigurerAdapter 
configure:
http.addFilterBefore(jwtAuthenticationTokenFilter, UsernamePasswordAuthenticationFilter.class); // JWT Filter 校驗部分
在登入的介面配置許可權
@PreAuthorize(
"hasAuthority('ddd:list')")

filter部分

package com.lzw.security.filter;

import com.alibaba.fastjson.JSON;
import com.lzw.security.common.GenericResponse;
import com.lzw.security.common.ServiceError;
import com.lzw.security.entity.User;
import com.lzw.security.service.SelfUserDetailsService;
import com.lzw.security.util.*;
import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; import org.springframework.security.core.GrantedAuthority; import org.springframework.security.core.context.SecurityContextHolder; 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; import java.util.HashMap; import java.util.Set; /** * @author: jamesluozhiwei 組2 * @description: 確保在一次請求只通過一次filter,而不需要重複執行 被springboot security 主類 呼叫 */ @Component @Slf4j public class JwtAuthenticationTokenFilter extends OncePerRequestFilter { @Value("${token.expirationMilliSeconds}") private long expirationMilliSeconds; @Autowired SelfUserDetailsService userDetailsService; @Autowired RedisUtil redisUtil; @Override protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException { //? String authHeader = request.getHeader("Authorization"); response.setCharacterEncoding("utf-8"); if (null == authHeader || !authHeader.startsWith("Bearer ")){ filterChain.doFilter(request,response);//token格式不正確 return; } String authToken = authHeader.substring("Bearer ".length()); String subject = JwtTokenUtil.parseToken(authToken);//獲取在token中自定義的subject,用作使用者標識,用來獲取使用者許可權 //獲取redis中的token資訊 if (!redisUtil.hasKey(authToken)){ //token 不存在 返回錯誤資訊 response.getWriter().write(JSON.toJSONString(GenericResponse.response(ServiceError.GLOBAL_ERR_NO_SIGN_IN))); return; } //獲取快取中的資訊(根據自己的業務進行拓展) HashMap<String,Object> hashMap = (HashMap<String, Object>) redisUtil.hget(authToken); //從tokenInfo中取出使用者資訊 ******** User user = new User(); user.setId(Long.parseLong(hashMap.get("id").toString())).setAuthorities((Set<? extends GrantedAuthority>) hashMap.get("authorities")); if (null == hashMap){ //使用者資訊不存在或轉換錯誤,返回錯誤資訊 response.getWriter().write(JSON.toJSONString(GenericResponse.response(ServiceError.GLOBAL_ERR_NO_SIGN_IN))); return; } //更新token過期時間 redisUtil.setKeyExpire(authToken,expirationMilliSeconds); //將資訊交給security ******* UsernamePasswordAuthenticationToken authenticationToken = new UsernamePasswordAuthenticationToken(user,null,user.getAuthorities()); authenticationToken.setDetails(new WebAuthenticationDetailsSource().buildDetails(request)); SecurityContextHolder.getContext().setAuthentication(authenticationToken); filterChain.doFilter(request,response); } }

第二種

另一種全部託管於spring Security

 mian class
WebSecurityConfigurer extends WebSecurityConfigurerAdapter 

@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception { auth .userDetailsService(customUserDetailsService) .passwordEncoder(passwordEncoder()); } 設定查詢方法 customUserDetailsService: //資料庫查資訊實現 UserDetailsService @Component public class CustomUserDetailsService implements UserDetailsService passwordEncoder() @Bean public PasswordEncoder passwordEncoder() { return new BCryptPasswordEncoder(); } 把放入token到redis的任務賦給handler public class CustomAuthenticationSuccessHandler implements AuthenticationSuccessHandler { @Autowired private RedisTemplate redisTemplate; private ObjectMapper objectMapper = new ObjectMapper(); @SneakyThrows @Override public void onAuthenticationSuccess(HttpServletRequest request, HttpServletResponse response, Authentication authentication){ String token; Long userId = 0l; if(authentication.getPrincipal() instanceof CustomUserDetailsUser){ // CustomUserDetailsUser userDetailsUser = (CustomUserDetailsUser) authentication.getPrincipal(); token = SecureUtil.md5(userDetailsUser.getUsername() + System.currentTimeMillis()); userId = userDetailsUser.getUserId(); }else { token = SecureUtil.md5(String.valueOf(System.currentTimeMillis())); } //redis放token redisTemplate.opsForValue().set(Constant.AUTHENTICATION_TOKEN + token,token,Constant.TOKEN_EXPIRE, TimeUnit.SECONDS); redisTemplate.opsForValue().set(token,userId,Constant.TOKEN_EXPIRE, TimeUnit.SECONDS); response.setCharacterEncoding(CharsetUtil.UTF_8); //網頁頭 response.setContentType(MediaType.APPLICATION_JSON_UTF8_VALUE); //登陸成功了加token到瀏覽器 ? PrintWriter printWriter = response.getWriter(); printWriter.append(objectMapper.writeValueAsString(R.ok().put(Constant.TOKEN,token))); }

在filter裡

先把token和使用者許可權存放到redis
並且
public class JwtAuthenticationTokenFilter extends OncePerRequestFilter {
...
 @Override
    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {
...
 UsernamePasswordAuthenticationToken authenticationToken = new UsernamePasswordAuthenticationToken(user,null,user.getAuthorities());
        authenticationToken.setDetails(new WebAuthenticationDetailsSource().buildDetails(request));
        SecurityContextHolder.getContext().setAuthentication(authenticationToken);
        filterChain.doFilter(request,response);

附贈小提示

controller介面部分

@RestController/Controller 注入 @RequestMapping 等 獲取請求與返回

springPreAuthorize 配置https://blog.csdn.net/weixin_39220472/article/details/80873268

    @RequestMapping("/info/{id}") 引數restful
    @PreAuthorize("hasRole('sys:config:info')") 許可權校驗
    public R info(@PathVariable("id") Long id){
        SysConfig config = sysConfigService.getById(id);

        return R.ok().put("config", config);
    }
value:  指定請求的實際地址, 比如 /action/info之類。
method:  指定請求的method型別, GET、POST、PUT、DELETE等
consumes: 指定處理請求的提交內容型別(Content-Type),例如application/json, text/html;
produces:    指定返回的內容型別,僅當request請求頭中的(Accept)型別中包含該指定型別才返回
params: 指定request中必須包含某些引數值是,才讓該方法處理
headers: 指定request中必須包含某些指定的header值,才能讓該方法處理請求

R: 一個vo

post 請求

獲取值https://blog.csdn.net/qq_41665356/article/details/80234392

可以用string vo形參和httprequest獲取

spring security爬坡

主要類分析

public class WebSecurityConfigurer extends WebSecurityConfigurerAdapter

Security主體類 功能實現基礎

@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {

自定義安全校驗 --> AuthenticationManagerBuilder
用於建立AuthenticationManager的SecurityBuilder。允許輕鬆構建記憶體身份驗證,LDAP身份驗證,基於JDBC的身份驗證,新增UserDetailsS​​ervice以及新增AuthenticationProvider。

auth.userDetailsService(customUserDetailsService) customUserDetailsService 這是一個繼承UserDetailsService 的Component 重寫方法loadUserByUsername 在資料庫裡校驗身份

protected void configure(HttpSecurity http) {  過濾的主方法,核心
antMatchers(urls[String 陣列]) 放行的url 陣列

.sessionManagement()
.sessionCreationPolicy(SessionCreationPolicy.STATELESS) 關閉session
csrf()
Adds CSRF support. This is activated by default when using WebSecurityConfigurerAdapter's default constructor. You can disable it using:
 @Configuration
 @EnableWebSecurity
 public class CsrfSecurityConfig extends WebSecurityConfigurerAdapter {

        @Override
     protected void configure(HttpSecurity http) throws Exception {
         http
             .csrf().disable()
             ...;
     }
 }
 
Returns:
the CsrfConfigurer for further customizations
Throws:
java.lang.Exception



! 在所有filter 之前

addFilterBefore
public HttpSecurity addFilterBefore(javax.servlet.Filter filter,
                                    java.lang.Class<? extends javax.servlet.Filter> beforeFilter)
Description copied from interface: HttpSecurityBuilder
Allows adding a Filter before one of the known Filter classes. The known Filter instances are either a Filter listed in HttpSecurityBuilder.addFilter(Filter) or a Filter that has already been added using HttpSecurityBuilder.addFilterAfter(Filter, Class) or HttpSecurityBuilder.addFilterBefore(Filter, Class).
Specified by:
addFilterBefore in interface HttpSecurityBuilder<HttpSecurity>
Parameters:
filter - the Filter to register before the type beforeFilter
beforeFilter - the Class of the known Filter.
Returns:
the HttpSecurity for further customizations
這個是所有的訪問都要過一下在這加過濾token的code

@SneakyThrows
lombok 甩出所有的錯誤
@EnableWebSecurity
https://blog.csdn.net/andy_zhang2007/article/details/90023901
該註解其實起到了如下效果 :

控制Spring Security是否使用除錯模式(通過註解屬性debug指定),預設為false,表示預設不使用除錯模式;
匯入 WebSecurityConfiguration,用於配置Web安全過濾器FilterChainProxy;
若干個WebSecurityConfigurerAdapter作用於一個WebSecurity生成一個最終使用的web安全過濾器FilterChainProxy
如果是Servlet 環境,匯入WebMvcSecurityConfiguration;
如果是OAuth2環境,匯入OAuth2ClientConfiguration;
使用註解@EnableGlobalAuthentication啟用全域性認證機制
————————————————
版權宣告:本文為CSDN博主「安迪源文」的原創文章,遵循CC 4.0 BY-SA版權協議,轉載請附上原文出處連結及本宣告。
原文連結:https://blog.csdn.net/andy_zhang2007/article/details/90023901

關於@EnableGlobalMethodSecurity 開啟spring

https://www.cnblogs.com/520playboy/p/7286085.html

@bean

注入例項到spring 工廠中以便於@Autowired等獲取