Spring Authorization Server,JWT教程_2 SpringSecurity與JWT整合

 2023-12-06 阅读 26 评论 0

摘要:3. SpringSecurity與JWT整合 依賴: <dependencies><dependency><groupId>org.mybatis.spring.boot</groupId><artifactId>mybatis-spring-boot-starter</artifactId><version>2.1.4</version></dependency><

3. SpringSecurity與JWT整合

依賴:

<dependencies><dependency><groupId>org.mybatis.spring.boot</groupId><artifactId>mybatis-spring-boot-starter</artifactId><version>2.1.4</version></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><dependency><groupId>io.jsonwebtoken</groupId><artifactId>jjwt</artifactId><version>0.9.1</version></dependency><dependency><groupId>com.alibaba</groupId><artifactId>druid-spring-boot-starter</artifactId><version>1.1.21</version></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.projectlombok</groupId><artifactId>lombok</artifactId><optional>true</optional></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-test</artifactId><scope>test</scope><exclusions><exclusion><groupId>org.junit.vintage</groupId><artifactId>junit-vintage-engine</artifactId></exclusion></exclusions></dependency>
</dependencies>

application.properties:

spring.thymeleaf.cache=false
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
spring.datasource.url=jdbc:mysql://localhost:3306/springsecurity001?useUnicode=true&characterEncoding=UTF-8&serverTimezone=GMT%2B8
spring.datasource.username=root
spring.datasource.password=123456
spring.datasource.type=com.alibaba.druid.pool.DruidDataSource
mybatis.mapper-locations=classpath:mapper/*.xml

Spring Authorization Server、啟動類SecurityJwtApplication:

@SpringBootApplication
@MapperScan("com.blu.mapper")
public class SecurityJwtApplication {public static void main(String[] args) {SpringApplication.run(SecurityJwtApplication.class, args);}@Beanpublic BCryptPasswordEncoder bcryptPasswordEncoder(){return new BCryptPasswordEncoder();}}

MyUser:

@Data
public class MyUser implements UserDetails {private Integer id;private String name;private String password;private List<MyRole> roles;@JsonIgnore@Overridepublic Collection<? extends GrantedAuthority> getAuthorities() {return roles;}@JsonIgnore@Overridepublic String getUsername() {return name;}@JsonIgnore@Overridepublic boolean isAccountNonExpired() {return true;}@JsonIgnore@Overridepublic boolean isAccountNonLocked() {return true;}@JsonIgnore@Overridepublic boolean isCredentialsNonExpired() {return true;}@JsonIgnore@Overridepublic boolean isEnabled() {return true;}}

MyRole:

@Data
public class MyRole implements GrantedAuthority {private Integer id;private String name;@JsonIgnore@Overridepublic String getAuthority() {return name;}}

jwt+redis?MyUserMapper:

public interface MyUserMapper {MyUser findByName(String name);
}
<?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.blu.mapper.MyUserMapper"><resultMap type="com.blu.entity.MyUser" id="myUserMap"><id column="uid" property="id"></id><result column="uname" property="name"></result><result column="password" property="password"></result><collection property="roles" ofType="com.blu.entity.MyRole"><id column="rid" property="id" /><result column="rname" property="name" /></collection></resultMap><select id="findByName" parameterType="String"resultMap="myUserMap">select u.id uid,u.name uname,u.password,r.id rid,r.name rnamefrom user u,role r,role_user ur where u.name = #{name} and ur.user_id = u.id and ur.role_id = r.id</select>
</mapper>

UserService:

public interface UserService extends UserDetailsService {}

UserServiceImpl:

@Service
public class UserServiceImpl implements UserService {@Autowiredprivate MyUserMapper myUserMapper;@Overridepublic UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {MyUser myUser = myUserMapper.findByName(username);return myUser;}}

JwtLoginFilter:

public class JwtLoginFilter extends AbstractAuthenticationProcessingFilter {public JwtLoginFilter(String defaultFilterProcessesUrl, AuthenticationManager authenticationManager) {super(new AntPathRequestMatcher(defaultFilterProcessesUrl));setAuthenticationManager(authenticationManager);}/*** 從登錄參數json數據中獲取用戶名密碼,然后調用AuthenticationManager.authenticate()方法進行校驗。*/@Overridepublic Authentication attemptAuthentication(HttpServletRequest req, HttpServletResponse resp) throws AuthenticationException, IOException, ServletException {//將用戶傳的json數據轉為user對象MyUser user = new ObjectMapper().readValue(req.getInputStream(),MyUser.class);return getAuthenticationManager().authenticate(new UsernamePasswordAuthenticationToken(user.getUsername(),user.getPassword()));}/*** 校驗成功*/@Overrideprotected void successfulAuthentication(HttpServletRequest request, HttpServletResponse response, FilterChain chain, Authentication authResult) throws IOException, ServletException {Collection<? extends GrantedAuthority> authorities = authResult.getAuthorities();StringBuffer sb = new StringBuffer();for (GrantedAuthority authority : authorities) {sb.append(authority.getAuthority()).append(",");}String jwt = Jwts.builder().claim("authorities", sb).setSubject(authResult.getName()).setExpiration(new Date(System.currentTimeMillis() + 60 * 60 * 1000))//設置過期時間.signWith(SignatureAlgorithm.HS512, "root@123")//設置加密方式,以及key.compact();//設置登錄成功后返回的信息Map<String,String> map = new HashMap<>();map.put("token",jwt);map.put("msg","登錄成功");response.setContentType("application/json;charset=utf-8");PrintWriter writer = response.getWriter();writer.write(new ObjectMapper().writeValueAsString(map));writer.flush();writer.close();}/*** 校驗失敗*/@Overrideprotected void unsuccessfulAuthentication(HttpServletRequest request, HttpServletResponse response, AuthenticationException failed) throws IOException, ServletException {Map<String,String> map = new HashMap<>();map.put("msg","登錄失敗");response.setContentType("application/json;charset=utf-8");PrintWriter writer = response.getWriter();writer.write(new ObjectMapper().writeValueAsString(map));writer.flush();writer.close();}
}

JwtFilter:

public class JwtFilter extends GenericFilterBean {@Overridepublic void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {HttpServletRequest req =  (HttpServletRequest) servletRequest;//從請求頭中獲取tokenString jwtToken = req.getHeader("authorization");Jws<Claims> jws = Jwts.parser().setSigningKey("root@123").parseClaimsJws(jwtToken.replace("Bearer", ""));Claims claims = jws.getBody();String username = claims.getSubject();//獲取角色List<GrantedAuthority> authorities = AuthorityUtils.commaSeparatedStringToAuthorityList((String) claims.get("authorities"));UsernamePasswordAuthenticationToken token = new UsernamePasswordAuthenticationToken(username,"",authorities);SecurityContextHolder.getContext().setAuthentication(token);filterChain.doFilter(servletRequest,servletResponse);}
}

測試接口:

@RestController
public class StringController {@GetMapping("hello")public String hello() {return "hello BLU!";}@GetMapping("hi")public String hi() {return "hi everyone!";}@GetMapping("admin")public String admin() {return "hello admin!";}}

Security配置類:

@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter{@Autowiredprivate UserServiceImpl userServiceImpl;@Autowiredprivate BCryptPasswordEncoder bcryptPasswordEncoder;@Overrideprotected void configure(HttpSecurity http) throws Exception {http.authorizeRequests().antMatchers(HttpMethod.GET,"/hi").permitAll().antMatchers("/hello").hasRole("vip1").antMatchers("/admin").hasRole("admin");http.formLogin().loginPage("/tologin").usernameParameter("name").passwordParameter("password").loginProcessingUrl("/login");http.csrf().disable();http.addFilterBefore(new JwtLoginFilter("/login",authenticationManager()),UsernamePasswordAuthenticationFilter.class).addFilterBefore(new JwtFilter(),UsernamePasswordAuthenticationFilter.class);}@Overrideprotected void configure(AuthenticationManagerBuilder auth) throws Exception {auth.userDetailsService(userServiceImpl).passwordEncoder(bcryptPasswordEncoder);}}

測試錯誤密碼登錄:
在這里插入圖片描述
測試正確密碼登錄:
在這里插入圖片描述
測試訪問(有權限):
在這里插入圖片描述
測試訪問(無權限):
在這里插入圖片描述
測試訪問(錯誤token):
在這里插入圖片描述

版权声明:本站所有资料均为网友推荐收集整理而来,仅供学习和研究交流使用。

原文链接:https://hbdhgg.com/5/189109.html

发表评论:

本站为非赢利网站,部分文章来源或改编自互联网及其他公众平台,主要目的在于分享信息,版权归原作者所有,内容仅供读者参考,如有侵权请联系我们删除!

Copyright © 2022 匯編語言學習筆記 Inc. 保留所有权利。

底部版权信息