最美情侣中文字幕电影,在线麻豆精品传媒,在线网站高清黄,久久黄色视频

歡迎光臨散文網(wǎng) 會員登陸 & 注冊

動力節(jié)點(diǎn)SpringSecurity框架視頻教程-springsecurity+

2023-04-19 14:41 作者:山藥當(dāng)當(dāng)  | 我要投稿

P18-P26學(xué)習(xí)筆記

10 SpringSecurity 返回json

前后端分離成為企業(yè)應(yīng)用開發(fā)中的主流,前后端分離通過json進(jìn)行交互,登錄成功和失敗后不用頁面跳轉(zhuǎn),而是一段json提示

10.1 新建模塊09-springsecurity-json

10.2 添加依賴

<dependency>

????<groupId>org.springframework.boot</groupId>

????<artifactId>spring-boot-starter-security</artifactId>

</dependency>

10.3 新建三個controller和獲取登錄用戶信息的controller

參照1.2.4 創(chuàng)建,可以直接拷貝過來

10.4 新建啟動類

com.powernode下新建Application類,學(xué)員自行創(chuàng)建

10.5 創(chuàng)建統(tǒng)一響應(yīng)類HttpResult

在com.powernode.vo中創(chuàng)建該類

@Data

@AllArgsConstructor

@NoArgsConstructor

@Builder

public class HttpResult {

????private Integer code;

????private String msg;

????private Object data;

????public HttpResult(Integer code, String msg) {

????????this.code = code;

????????this.msg = msg;

????}

}

10.6 創(chuàng)建登錄成功處理器

com.powernode.config 包下創(chuàng)建

@Component

public class MyAutheticationSuccessHandle implements AuthenticationSuccessHandler {

@Resource

????private ObjectMapper objectMapper;


????@Override

????public void onAuthenticationSuccess(HttpServletRequest request, HttpServletResponse response, Authentication authentication) throws IOException, ServletException {

????????response.setCharacterEncoding("UTF-8");

????????response.setContentType("application/json;charset=utf-8");

????????HttpResult httpResult = new HttpResult(200, "登錄成功", authentication);

????????String str = objectMapper.writeValueAsString(httpResult);

????????response.getWriter().write(str);

????????response.getWriter().flush();

????}

}

10.7 創(chuàng)建登錄失敗處理器

/**

?* 登陸失敗的處理器

?*/

@Component

public class AppAuthenticationFailureHandler implements AuthenticationFailureHandler {


????@Resource

????private ObjectMapper objectMapper;



????/**

?????* @param request 當(dāng)前的請求對象

?????* @param response 當(dāng)前的響應(yīng)對象

?????* @param exception 失敗的原因的異常

?????* @throws IOException

?????* @throws ServletException

?????*/

????@Override

????public void onAuthenticationFailure(HttpServletRequest request, HttpServletResponse response, AuthenticationException exception) throws IOException, ServletException {

????????System.err.println("登陸失敗");

????????//設(shè)置響應(yīng)編碼

????????response.setCharacterEncoding("UTF-8");

????????response.setContentType("application/json;charset=utf-8");

????????//返回JSON出去

????????HttpResult result=new HttpResult(-1,"登陸失敗");

????????if(exception instanceof BadCredentialsException){

????????????result.setData("密碼不正確");

????????}else if(exception instanceof DisabledException){

????????????result.setData("賬號被禁用");

????????}else if(exception instanceof UsernameNotFoundException){

????????????result.setData("用戶名不存在");

????????}else if(exception instanceof CredentialsExpiredException){

????????????result.setData("密碼已過期");

????????}else if(exception instanceof AccountExpiredException){

????????????result.setData("賬號已過期");

????????}else if(exception instanceof LockedException){

????????????result.setData("賬號被鎖定");

????????}else{

????????????result.setData("未知異常");

????????}

????????//把result轉(zhuǎn)成JSON

????????String json = objectMapper.writeValueAsString(result);

????????//響應(yīng)出去

????????PrintWriter out = response.getWriter();

????????out.write(json);

????????out.flush();

????}

}

10.8 創(chuàng)鍵無權(quán)限處理器

/**

?* 無權(quán)限的處理器

?*/

@Component

public class AppAccessDeniedHandler implements AccessDeniedHandler {


????//聲明一個把對象轉(zhuǎn)成JSON的對象

@Resource

????private ObjectMapper objectMapper;


????@Override

????public void handle(HttpServletRequest request, HttpServletResponse response, AccessDeniedException accessDeniedException) throws IOException, ServletException {

????????//設(shè)置響應(yīng)編碼

????????response.setCharacterEncoding("UTF-8");

????????response.setContentType("application/json;charset=utf-8");

????????//返回JSON出去

????????HttpResult result=new HttpResult(-1,"您沒有權(quán)限訪問");

????????//把result轉(zhuǎn)成JSON

????????String json = objectMapper.writeValueAsString(result);

????????//響應(yīng)出去

????????PrintWriter out = response.getWriter();

????????out.write(json);

????????out.flush();

????}

}

10.9 創(chuàng)建登出(退出)處理器

/**

?* 退出成功的處理器

?*/

@Component

public class AppLogoutSuccessHandler implements LogoutSuccessHandler {


????//聲明一個把對象轉(zhuǎn)成JSON的對象

@Resource

????private ObjectMapper objectMapper;


????/**

?????*

?????* @param request

?????* @param response

?????* @param authentication 當(dāng)前退出的用戶對象

?????* @throws IOException

?????* @throws ServletException

?????*/

????@Override

????public void onLogoutSuccess(HttpServletRequest request, HttpServletResponse response, Authentication authentication) throws IOException, ServletException {

????????System.out.println("退出成功");

????????//設(shè)置響應(yīng)編碼

????????response.setCharacterEncoding("UTF-8");

????????response.setContentType("application/json;charset=utf-8");

????????//返回JSON出去

????????HttpResult result=new HttpResult(200,"退出成功");

????????//把result轉(zhuǎn)成JSON

????????String json = objectMapper.writeValueAsString(result);

????????//響應(yīng)出去

????????PrintWriter out = response.getWriter();

????????out.write(json);

????????out.flush();

????}

}

10.10 創(chuàng)建用戶配置類

@Configuration

public class MySecurityUserConfig {

????@Bean

????public UserDetailsService userDetailService() {

// ???????使用org.springframework.security.core.userdetails.User類來定義用戶

????????//定義用戶

????????UserDetails user1 = User.builder()

????????????????.username("eric")

????????????????.password(passwordEncoder().encode("123456"))

????????????????.roles("student")

????????????????.build();

????????UserDetails user2 = User.builder()

????????????????.username("thomas")

????????????????.password(passwordEncoder().encode("123456"))

????????????????.roles("teacher")

????????????????.build();

????????UserDetails user3 = User.builder()

????????????????.username("admin")

????????????????.password(passwordEncoder().encode("123456"))

????????????????.roles("admin")

????????????????.build();

????????//創(chuàng)建用戶

????????InMemoryUserDetailsManager userDetailsManager = new InMemoryUserDetailsManager();

????????userDetailsManager.createUser(user1);

????????userDetailsManager.createUser(user2);

????????userDetailsManager.createUser(user3);

????????return userDetailsManager;

????}


????/*

?????* 從?Spring5 開始,強(qiáng)制要求密碼要加密

?????* @return

?????*/

????@Bean

????public PasswordEncoder passwordEncoder(){

????????//使用加密算法對密碼進(jìn)行加密

????????return new BCryptPasswordEncoder();

????}


}


10.11 安全配置類WebSecurityConfig

@Configuration

public class WebSecurityConfig extends WebSecurityConfigurerAdapter {


????// 注入登陸成功的處理器

????@Autowired

????private AutheticationSuccessHandle successHandler;


????// 注入登陸失敗的處理器

????@Autowired

????private AppAuthenticationFailureHandler failureHandler;


????// 注入沒有權(quán)限的處理器

????@Autowired

????private AppAccessDeniedHandler accessDeniedHandler;


????// ?注入退出成功的處理器

????@Autowired

????private AppLogoutSuccessHandler logoutSuccessHandler;


????@Override

????protected void configure(HttpSecurity http) throws Exception {

????????http.exceptionHandling().accessDeniedHandler(accessDeniedHandler);

????????http.formLogin().successHandler(successHandler).failureHandler(failureHandler).permitAll();

????????http.logout().logoutSuccessHandler(logoutSuccessHandler);

????????http.authorizeRequests().mvcMatchers("/teacher/**").hasRole("teacher").anyRequest().authenticated();

????}

}

10.12 啟動程序

10.13 訪問測試

可以使用admin用戶實(shí)驗(yàn)登錄失敗、登錄成功、退出和訪問http://localhost:8080/teacher/query 查看無權(quán)訪問的效果

11 使用UserDetailsService獲取用戶認(rèn)證信息

11.1 新建子模塊10-springsecurity-userdetailservice

11.2 添加依賴

<dependency>

????<groupId>org.springframework.boot</groupId>

????<artifactId>spring-boot-starter-security</artifactId>

</dependency>

11.3 新建啟動類

com.powernode包下新建啟動類Application,學(xué)員自行創(chuàng)建

11.4 新建三個controller

參照1.2.4 創(chuàng)建,可以直接拷貝過來

11.5 新建獲取登錄用戶認(rèn)證信息的controller

拷貝7.1 即可

11.6 新建用戶信息類

com.powernode.vo包下新建SecurityUser 類,該類實(shí)現(xiàn)接口UserDetails接口

public class SecurityUser implements UserDetails {

????@Override

????public Collection<? extends GrantedAuthority> getAuthorities() {

????????return null;

????}


????@Override

????public String getPassword() {

????????//明文為123456

????????return "$2a$10$KyXAnVcsrLaHMWpd3e2xhe6JmzBi.3AgMhteFq8t8kjxmwL8olEDq";

????}


????@Override

????public String getUsername() {

????????return "thomas";

????}


????@Override

????public boolean isAccountNonExpired() {

????????return true;

????}


????@Override

????public boolean isAccountNonLocked() {

????????return true;

????}


????@Override

????public boolean isCredentialsNonExpired() {

????????return true;

????}


????@Override

????public boolean isEnabled() {

????????return true;

????}

}

代碼說明:

用戶實(shí)體類需要實(shí)現(xiàn)UserDetails接口,并實(shí)現(xiàn)該接口中的7個方法, UserDetails 接口的7個方法如下圖:

11.7 新建類實(shí)現(xiàn)UserDetailService接口

com.powernode.service.impl 包下新建UserServiceImpl 實(shí)現(xiàn)UserDetailService

@Service

public class UserServiceImpl implements UserDetailsService {

????@Override

????public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {

????????SecurityUser securityUser= new SecurityUser();

????????if(username==null || !username.equals(securityUser.getUsername())){

????????????throw new UsernameNotFoundException("該用戶不存在");

????????}

????????return securityUser;

????}

}



11.8 新建安全配置類

com.powernode.config下新建WebSecurityConfig類,配置密碼編碼器

@Configuration

@Slf4j

public class WebSecurityConfig extends WebSecurityConfigurerAdapter {

????@Bean

????public PasswordEncoder passwordEncoder(){

????????return new BCryptPasswordEncoder();

????}

}

啟動程序,并使用瀏覽器訪問程序:http://localhost:8080/student/query

發(fā)現(xiàn)需要登錄,使用thomas/123456 登錄后,即可正常訪問。

訪問:http://localhost:8080/getLoginUserInfo

發(fā)現(xiàn)該用戶并沒有權(quán)限信息

11.9 配置用戶權(quán)限信息

修改SecurityUser類中的getAuthorities 方法

????@Override

????public Collection<? extends GrantedAuthority> getAuthorities() {

???????GrantedAuthority g1=()->"student:query"; //使用lambda表達(dá)式

// ??????GrantedAuthority g1=new SimpleGrantedAuthority("student:query");

???????List<GrantedAuthority> grantedAuthorityList=new ArrayList<>();

???????grantedAuthorityList.add(g1);

???????return grantedAuthorityList;

????}

11.10 修改要訪問controller中的方法需要哪些權(quán)限

修改WebSecurityConfig,添加全局方法攔截注解@EnableGlobalMethodSecurity(prePostEnabled = true)

注意可以去掉:@Configuration注解了


修改StudentController

添加?@PreAuthorize("hasAuthority('student:query')") 注解修改后如下:

@RestController

@RequestMapping("/student")

public class StudentController {

????@GetMapping("/query")

????@PreAuthorize("hasAuthority('student:query')")

????public String queryInfo(HttpServletRequest request){

????????return "I am a student,My name is XXX";

????}

}

修改TeacherController

添加?@PreAuthorize("hasAuthority(teacher:query')") 注解修改后如下:

@RestController

@RequestMapping("/teacher")

public class TeacherController {

????@GetMapping("/query")

????@PreAuthorize("hasAuthority('teacher:query')")

????public String queryInfo(){

????????return "I am a teacher,My name is Thomas";

????}

}


啟動測試,使用thomas/123456 登錄系統(tǒng),發(fā)現(xiàn)可以訪問student/query,不可以訪問teacher/query

再次訪問:http://localhost:8080/getLoginUserInfo?查看用戶信息

11.11 為什么講這個示例?

是為了使用數(shù)據(jù)庫存儲用戶角色權(quán)限信息做準(zhǔn)備,只要從數(shù)據(jù)庫中取出數(shù)據(jù)存儲到實(shí)現(xiàn)UserDetails 的接口的類中即可,比如SecurityUser 中即可。

12 基于數(shù)據(jù)庫的認(rèn)證

12.1 創(chuàng)建數(shù)據(jù)庫security_study和表

創(chuàng)建數(shù)據(jù)庫security_study

導(dǎo)入數(shù)據(jù)庫腳本security_study.sql

12.2 創(chuàng)建模塊11-springsecurity-database-authentication

12.3 添加依賴

<parent>

????<groupId>org.springframework.boot</groupId>

????<artifactId>spring-boot-starter-parent</artifactId>

????<version>2.6.13</version>

</parent>


<properties>

????<maven.compiler.source>8</maven.compiler.source>

????<maven.compiler.target>8</maven.compiler.target>

????<java.version>8</java.version>

</properties>


<dependencies>

????<dependency>

????????<groupId>org.springframework.boot</groupId>

????????<artifactId>spring-boot-starter-web</artifactId>

????</dependency>

????<dependency>

????????<groupId>org.springframework.boot</groupId>

????????<artifactId>spring-boot-starter-test</artifactId>

????????<scope>test</scope>

????</dependency>

????<dependency>

????????<groupId>org.springframework.boot</groupId>

????????<artifactId>spring-boot-starter-security</artifactId>

????</dependency>

????<dependency>

????????<groupId>mysql</groupId>

????????<artifactId>mysql-connector-java</artifactId>

????????<scope>runtime</scope>

????</dependency>

????<dependency>

????????<groupId>org.mybatis.spring.boot</groupId>

????????<artifactId>mybatis-spring-boot-starter</artifactId>

????????<version>2.2.2</version>

????</dependency>

????<dependency>

????????<groupId>org.projectlombok</groupId>

????????<artifactId>lombok</artifactId>

????????<optional>true</optional>

????</dependency>

</dependencies>

<build>

????<plugins>

????????<plugin>

????????????<groupId>org.springframework.boot</groupId>

????????????<artifactId>spring-boot-maven-plugin</artifactId>

????????</plugin>

????</plugins>

</build>

12.4 配置數(shù)據(jù)源和mybatis

新建配置文件application.yml并配置數(shù)據(jù)源和mybatis

spring:

??datasource:

????driver-class-name: com.mysql.cj.jdbc.Driver

????url: jdbc:mysql://127.0.0.1:3306/security_study?useUnicode=true&characterEncoding=UTF-8&serverTimezone=Asia/Shanghai

????username: root

????password: root

mybatis:

??type-aliases-package: com.powernode.entity

??configuration:

????map-underscore-to-camel-case: true

????log-impl: org.apache.ibatis.logging.stdout.StdOutImpl

??mapper-locations: classpath:mapper/*.xml


12.5 新建各個包

12.6 新建用戶實(shí)體類

com.powernode.entity 包下新建用戶實(shí)體類

@Data

public class SysUser implements Serializable {

????private Integer userId;

????private String username;

????private String password;

????private String sex;

????private String address;

????private Integer enabled;

????private Integer accountNoExpired;

????private Integer credentialsNoExpired;

????private Integer accountNoLocked;


}

12.7 新建用戶mapper和映射文件

com.powernode.dao下新建

public interface SysUserDao {

????/**

?????* 根據(jù)用戶名獲取用戶信息

?????* @param username

?????* @return

?????*/

????SysUser getByUserName(@Param("username") String username);

}

mapper下新建映射文件SysUserMapper.xml

<?xml version="1.0" encoding="UTF-8" ?>

<!DOCTYPE mapper

????????PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"

????????"http://mybatis.org/dtd/mybatis-3-mapper.dtd">

<mapper namespace="com.powernode.dao.SysUserDao">

????<select id="getByUserName" resultType="sysUser">

????????select user_id,username,password,sex,address,enabled,account_no_expired,credentials_no_expired,account_no_locked

????????from sys_user where username=#{username}

????</select>

</mapper>

注意select后面不要使用*。

12.8 新建啟動類

com.powernode包下新建啟動類

@SpringBootApplication

@MapperScan("com.powernode.dao")

public class Application {

????public static void main(String[] args) {

????????SpringApplication.run(Application.class,args);

????}

}

12.9 單元測試

測試dao

@SpringBootTest

class SysUserDaoTest {

????@Resource

????private SysUserDao sysUserDao;

????@Test

????void getByUserName() {

????????SysUser sysUser = sysUserDao.getByUserName("obama");

????????assertNotNull(sysUser);

????}

}


注意單元測試要測試哪些:dao--service-controller,實(shí)體類一般不需要測試

12.10 新建安全用戶類

com.powernode.vo包下新建類

public class SecurityUser implements UserDetails {

????private ?final SysUser sysUser;


????public SecurityUser(SysUser sysUser) {

????????this.sysUser=sysUser;

????}


????@Override

????public Collection<? extends GrantedAuthority> getAuthorities() {

????????return null;

????}


????@Override

????public String getPassword() {

????????String userPassword=this.sysUser.getPassword();

//注意清除密碼

this.sysUser.setPassword(null);

return userPassword;


????}


????@Override

????public String getUsername() {

????????return sysUser.getUsername();

????}


????@Override

????public boolean isAccountNonExpired() {

????????return sysUser.getAccountNoExpired().equals(1);

????}


????@Override

????public boolean isAccountNonLocked() {

????????return sysUser.getAccountNoLocked().equals(1);

????}


????@Override

????public boolean isCredentialsNonExpired() {

????????return sysUser.getCredentialsNoExpired().equals(1);

????}


????@Override

????public boolean isEnabled() {

????????return sysUser.getEnabled().equals(1);

????}

}

12.11新建UserServiceImpl 實(shí)現(xiàn)UserDetailService接口

@Service

public class UserServiceImpl implements UserDetailsService {

????@Resource

????private SysUserDao sysUserDao;


????@Override

????public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {

????????SysUser sysUser = sysUserDao.getByUserName(username);

????????if(null==sysUser){

????????????throw new UsernameNotFoundException("賬號不存在");

????????}

????????return new SecurityUser(sysUser);

????}

}

12.12 新建service單元測試

@SpringBootTest

class UserServiceImplTest {

????@Resource

????private UserServiceImpl userService;

????@Test

????void loadUserByUsername() {

????????UserDetails userDetails = userService.loadUserByUsername("obama");

????????assertNotNull(userDetails);

????}

}

12.13 新建兩個控制器

@RestController

@Slf4j

@RequestMapping("/student")

public class StudentController {

????@GetMapping("/query")

????public String queryInfo(){

????????return "query student";

????}

????@GetMapping("/add")

????public String addInfo(){

????????return "add ?student!";

????}

????@GetMapping("/update")

????public String updateInfo(){

????????return "update student";

????}

????@GetMapping("/delete")

????public String deleteInfo(){

????????return "delete ?student!";

????}

????@GetMapping("/export")

????public String exportInfo(){

????????return "export ?student!";

????}

}


@RestController

@Slf4j

@RequestMapping("/teacher")

public class TeacherController {

????@GetMapping("/query")

????@PreAuthorize("hasAuthority('teacher:query')")

????public String queryInfo(){

????????return "I am a teacher!";

????}

}

12.14 新建獲取登錄用戶認(rèn)證信息的controller

從7.1 中拷貝即可

12.15 新建web安全配置類

@EnableGlobalMethodSecurity(prePostEnabled = true)

@Slf4j

public class WebSecurityConfig extends WebSecurityConfigurerAdapter {


????@Bean

????public PasswordEncoder passwordEncoder() {

????????return new BCryptPasswordEncoder();

????}


????@Override

????protected void configure(HttpSecurity http) throws Exception {

????????http.authorizeRequests().anyRequest().authenticated();

????????http.formLogin();

????}

}

啟動并進(jìn)行各種測試

使用thomas和obama分別登錄測試,發(fā)現(xiàn)student/query等能訪問,teacher/query 不能訪問,原因

http://localhost:8080/getLoginUserInfo


發(fā)現(xiàn)用戶沒有權(quán)限,但是/teacher/query 需要訪問權(quán)限


動力節(jié)點(diǎn)SpringSecurity框架視頻教程-springsecurity+的評論 (共 條)

分享到微博請遵守國家法律
东港市| 呼伦贝尔市| 峨边| 灵璧县| 陆河县| 襄城县| 樟树市| 南乐县| 诸暨市| 襄汾县| 武乡县| 呼图壁县| 绵阳市| 泰安市| 绥滨县| 邯郸县| 永善县| 宜阳县| 平定县| 楚雄市| 分宜县| 法库县| 德阳市| 长岭县| 聂荣县| 万载县| 贵德县| 庆安县| 平武县| 宣武区| 安庆市| 云南省| 开鲁县| 双牌县| 井陉县| 鄱阳县| 灌阳县| 定边县| 历史| 霍林郭勒市| 凉城县|