日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

【笔记】springboot+spring security登录流程实现

發(fā)布時(shí)間:2024/9/30 编程问答 37 豆豆
生活随笔 收集整理的這篇文章主要介紹了 【笔记】springboot+spring security登录流程实现 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

在登錄控制器中添加一個(gè)登錄接口login,在其中驗(yàn)證驗(yàn)證碼、用戶名、密碼信息。匹配成功之后,執(zhí)行Spring Security的登錄認(rèn)證機(jī)制。登錄成功之后,返回Token令牌憑證。
SysLoginController

@RestController public class SysLoginController {@Autowiredprivate Producer producer;@Autowiredprivate SysUserService sysUserService;@Autowiredprivate SysLoginLogService sysLoginLogService;@Autowiredprivate AuthenticationManager authenticationManager;@GetMapping("captcha.jpg")public void captcha(HttpServletResponse response, HttpServletRequest request) throws ServletException, IOException {response.setHeader("Cache-Control", "no-store, no-cache");response.setContentType("image/jpeg");// 生成文字驗(yàn)證碼String text = producer.createText();// 生成圖片驗(yàn)證碼BufferedImage image = producer.createImage(text);// 保存到驗(yàn)證碼到 sessionrequest.getSession().setAttribute(Constants.KAPTCHA_SESSION_KEY, text);ServletOutputStream out = response.getOutputStream();ImageIO.write(image, "jpg", out); IOUtils.closeQuietly(out);}/*** 登錄接口*/@PostMapping(value = "/login")public HttpResult login(@RequestBody LoginBean loginBean, HttpServletRequest request) throws IOException {String username = loginBean.getAccount();String password = loginBean.getPassword();String captcha = loginBean.getCaptcha();// 從session中獲取之前保存的驗(yàn)證碼跟前臺傳來的驗(yàn)證碼進(jìn)行匹配Object kaptcha = request.getSession().getAttribute(Constants.KAPTCHA_SESSION_KEY);if(kaptcha == null){return HttpResult.error("驗(yàn)證碼已失效");}if(!captcha.equals(kaptcha)){return HttpResult.error("驗(yàn)證碼不正確");}// 用戶信息SysUser user = sysUserService.findByName(username);// 賬號不存在、密碼錯(cuò)誤if (user == null) {return HttpResult.error("賬號不存在");}if (!PasswordUtils.matches(user.getSalt(), password, user.getPassword())) {return HttpResult.error("密碼不正確");}// 賬號鎖定if (user.getStatus() == 0) {return HttpResult.error("賬號已被鎖定,請聯(lián)系管理員");}// 系統(tǒng)登錄認(rèn)證JwtAuthenticatioToken token = SecurityUtils.login(request, username, password, authenticationManager);// 記錄登錄日志// sysLoginLogService.writeLoginLog(username, IPUtils.getIpAddr(request));return HttpResult.ok(token);}}

(1)將用戶名密碼的認(rèn)證信息封裝到JwtAuthenticatioToken對象。
(2)通過調(diào)用authenticationManager.authenticate(token)執(zhí)行認(rèn)證流程。
(3)通過SecurityContextHolder將認(rèn)證信息保存到Security上下文。
(4)通過JwtTokenUtils.generateToken(authentication)生成token并返回。
serializable接口的作用:1、存儲對象在存儲介質(zhì)中,以便在下次使用的時(shí)候,可以很快捷的重建一個(gè)副本;2、便于數(shù)據(jù)傳輸,尤其是在遠(yuǎn)程調(diào)用的時(shí)候
Serializable接口是啟用其序列化功能的接口。實(shí)現(xiàn)java.io.Serializable 接口的類是可序列化的。沒有實(shí)現(xiàn)此接口的類將不能使它們的任意狀態(tài)被序列化或逆序列化

Spring Security 應(yīng)用級別的安全主要包含兩個(gè)主要部分,即登錄認(rèn)證(Authentication)和訪問授權(quán)(Authorization),首先用戶登錄的時(shí)候傳入登錄信息,登錄驗(yàn)證器完成登錄認(rèn)證并將登錄認(rèn)證好的信息存儲到請求上下文,然后在進(jìn)行其他操作,如接口訪問、方法調(diào)用時(shí),權(quán)限認(rèn)證器從上下文中獲取登錄認(rèn)證信息,然后根據(jù)認(rèn)證信息獲取權(quán)限信息,通過權(quán)限信息和特定的授權(quán)策略決定是否授權(quán)。

spring secuirty:
https://www.cnblogs.com/xifengxiaoma/p/10020960.html

Spring Security的登錄認(rèn)證過程是委托給 AuthenticationManager 完成的,它先是解析出用戶名和密碼,然后把用戶名和密碼封裝到一個(gè)UsernamePasswordAuthenticationToken 中,傳遞給 AuthenticationManager,交由 AuthenticationManager 完成實(shí)際的登錄認(rèn)證過程

spring security的關(guān)鍵配置:

安全配置類
下面這個(gè)配置類是Spring Security的關(guān)鍵配置。

在這個(gè)配置類中,我們主要做了以下幾個(gè)配置:

  • 訪問路徑URL的授權(quán)策略,如登錄、Swagger訪問免登錄認(rèn)證等

  • 指定了登錄認(rèn)證流程過濾器 JwtLoginFilter,由它來觸發(fā)登錄認(rèn)證

  • 指定了自定義身份認(rèn)證組件 JwtAuthenticationProvider,并注入 UserDetailsService

  • 指定了訪問控制過濾器 JwtAuthenticationFilter,在授權(quán)時(shí)解析令牌和設(shè)置登錄狀態(tài)

  • 指定了退出登錄處理器,因?yàn)槭乔昂蠖朔蛛x,防止內(nèi)置的登錄處理器在后臺進(jìn)行跳轉(zhuǎn)

  • WebSecurityConfig.java

    package com.louis.springboot.spring.security.config;import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.http.HttpMethod; import org.springframework.security.authentication.AuthenticationManager; import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder; import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity; import org.springframework.security.config.annotation.web.builders.HttpSecurity; import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter; import org.springframework.security.core.userdetails.UserDetailsService; import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter; import org.springframework.security.web.authentication.logout.HttpStatusReturningLogoutSuccessHandler;import com.louis.springboot.spring.security.security.JwtAuthenticationFilter; import com.louis.springboot.spring.security.security.JwtAuthenticationProvider; import com.louis.springboot.spring.security.security.JwtLoginFilter;/*** Security Config* @author Louis* @date Nov 28, 2018*/ @Configuration @EnableWebSecurity @EnableGlobalMethodSecurity(prePostEnabled = true) public class WebSecurityConfig extends WebSecurityConfigurerAdapter {@Autowiredprivate UserDetailsService userDetailsService;@Overridepublic void configure(AuthenticationManagerBuilder auth) throws Exception {// 使用自定義登錄身份認(rèn)證組件auth.authenticationProvider(new JwtAuthenticationProvider(userDetailsService));}@Overrideprotected void configure(HttpSecurity http) throws Exception {// 禁用 csrf, 由于使用的是JWT,我們這里不需要csrfhttp.cors().and().csrf().disable().authorizeRequests()// 跨域預(yù)檢請求.antMatchers(HttpMethod.OPTIONS, "/**").permitAll()// 登錄URL.antMatchers("/login").permitAll()// swagger.antMatchers("/swagger-ui.html").permitAll().antMatchers("/swagger-resources").permitAll().antMatchers("/v2/api-docs").permitAll().antMatchers("/webjars/springfox-swagger-ui/**").permitAll()// 其他所有請求需要身份認(rèn)證.anyRequest().authenticated();// 退出登錄處理器http.logout().logoutSuccessHandler(new HttpStatusReturningLogoutSuccessHandler());// 開啟登錄認(rèn)證流程過濾器http.addFilterBefore(new JwtLoginFilter(authenticationManager()), UsernamePasswordAuthenticationFilter.class);// 訪問控制時(shí)登錄狀態(tài)檢查過濾器http.addFilterBefore(new JwtAuthenticationFilter(authenticationManager()), UsernamePasswordAuthenticationFilter.class);}@Bean@Overridepublic AuthenticationManager authenticationManager() throws Exception {return super.authenticationManager();}}

    實(shí)例(自己配置固定的用戶名和密碼)

    //Spring Security為Web應(yīng)用提供了一個(gè)適配器類WebSecurityConfigurerAdapter, // 該類實(shí)現(xiàn)了WebSecurityConfigurer <WebSecurity>接口,并提供了兩個(gè)configure方法用于認(rèn)證和授權(quán)操作。 開發(fā)者創(chuàng)建自己的Spring Security適配器類是非常簡單的, // 只需定義一個(gè)繼承WebSecurityConfigurerAdapter的類,并在該類中使用@Configuration注解, // 就可以通過重寫兩個(gè)configure方法來配置所需要的安全配置。自@Configuration public class SecutiryConfig extends WebSecurityConfigurerAdapter {//Spring Security為Web應(yīng)用提供了一個(gè)適配器類WebSecurityConfigurerAdapter,// 該類實(shí)現(xiàn)了WebSecurityConfigurer <WebSecurity>接口,并提供了兩個(gè)configure方法用于認(rèn)證和授權(quán)操作。// 開發(fā)者創(chuàng)建自己的Spring Security適配器類是非常簡單的,// 只需定義一個(gè)繼承WebSecurityConfigurerAdapter的類,// 并在該類中使用@Configuration注解,// 就可以通過重寫兩個(gè)configure方法來配置所需要的安全配置。 @Override public void configure(AuthenticationManagerBuilder auth) throws Exception{BCryptPasswordEncoder passwordEncoder = new BCryptPasswordEncoder();String password = passwordEncoder.encode("123");auth.inMemoryAuthentication().withUser("root").password(password).roles("admin"); //如果沒有寫.roles,會報(bào)錯(cuò)Cannot pass a null GrantedAuthority collection }@BeanPasswordEncoder getPasswordEncoder() {return new BCryptPasswordEncoder();}@Overrideprotected void configure(HttpSecurity http) throws Exception{http.formLogin()//這句表示自定義自己的登陸界面.loginPage("/login.html")//登錄頁面設(shè)置.loginProcessingUrl("/user") //登錄訪問路徑.defaultSuccessUrl("/test").permitAll() //表示登陸成功后要跳轉(zhuǎn)到的路徑.and().authorizeRequests().antMatchers("/","/test/hello").permitAll()//這個(gè)用來設(shè)置哪些路徑可以直接訪問,不需要認(rèn)證.anyRequest().authenticated().and().csrf().disable();}}

    創(chuàng)建html:

    <!DOCTYPE html> <html lang="en"> <head><meta charset="UTF-8"><title>Title</title> </head> <body> <form action="/user" method="post">用戶名:<input type="text" name="username"><br>input的name必須要為username和password,否則Security得不到其中的值</br>訪問localhost:8080/login.html 顯示此表單,然后輸入自己配置類中設(shè)置的用戶名和密碼則可以進(jìn)入登陸成功后的跳轉(zhuǎn)路徑即/test<br>@GetMapping("test")public String index(){return "hello index";}<br>密碼:<input type="text" name="password"><br><input type="submit" value="login"></form> </body> </html>

    controller:

    @RestController public class jpaUserController {@GetMapping("test")public String index(){return "hello index";}}//在實(shí)際應(yīng)用中,可以查詢數(shù)據(jù)庫獲取用戶和權(quán)限, // 這時(shí)需要自定義實(shí)現(xiàn)userdetails.UserDetailsService接口的類, // 并重寫public UserDetails loadUserByUsername(String username)方法 // 查詢對應(yīng)的用戶和權(quán)限。:


    輸入root 123

    總結(jié)

    以上是生活随笔為你收集整理的【笔记】springboot+spring security登录流程实现的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。