iis服务器助手广告广告
返回顶部
首页 > 资讯 > 服务器 >springboot整合springsecurity+oauth2.0密码授权模式
  • 268
分享到

springboot整合springsecurity+oauth2.0密码授权模式

springboot服务器java 2023-08-18 16:08:57 268人浏览 薄情痞子
摘要

SpringBoot整合springsecurity+oauth2.0 本文采用的springboot去整合springsecurity,采用oauth2.0授权认证,使用Jwt对token增强。本文仅为学习记录,如有不足多谢提出。 OAu

SpringBoot整合springsecurity+oauth2.0

本文采用的springboot去整合springsecurity,采用oauth2.0授权认证,使用Jwt对token增强。本文仅为学习记录,如有不足多谢提出。

OAuth2 简介

OAuth 2.0是用于授权的行业标准协议。OAuth 2.0为简化客户端开发提供了特定的授权流,包括WEB应用、桌面应用、移动端应用等。

OAuth2 相关名词解释

  • Resource owner(资源拥有者):拥有该资源的最终用户,他有访问资源的账号密码;
  • Resource server(资源服务器):拥有受保护资源的服务器,如果请求包含正确的访问令牌,可以访问资源;
  • Client(客户端):访问资源的客户端,会使用访问令牌去获取资源服务器的资源,可以是浏览器、移动设备或者服务器;
  • Authorization server(认证服务器):用于认证用户的服务器,如果客户端认证通过,发放访问资源服务器的令牌。

四种授权模式

  • Authorization Code(授权码模式):正宗的OAuth2的授权模式,客户端先将用户导向认证服务器,登录后获取授权码,然后进行授权,最后根据授权码获取访问令牌;
  • Implicit(简化模式):和授权码模式相比,取消了获取授权码的过程,直接获取访问令牌;
  • Resource Owner PassWord Credentials(密码模式):客户端直接向用户获取用户名和密码,之后向认证服务器获取访问令牌;
  • Client Credentials(客户端模式):客户端直接通过客户端认证(比如client_id和client_secret)从认证服务器获取访问令牌。

主要pom文件引入

                    org.springframework.boot            spring-boot-starter-security                            org.springframework.security.oauth            spring-security-oauth2            2.2.6.RELEASE                                    org.springframework.security            spring-security-jwt            1.1.0.RELEASE                 #本文采用的springboot版本为2.6.3,由于Spring Security 在 Spring Boot 2.7.0 中已弃用的 WebSecurityConfigurerAdapter 所有在配置。所以在配置SpringSecurity配置时,原先configure采用bena配置SecurityFilterChain bean

编写实体类

用户类

package com.example.health.model;import com.alibaba.fastJSON.annotation.jsONField;import lombok.Data;import org.springframework.security.core.GrantedAuthority;import org.springframework.security.core.authority.SimpleGrantedAuthority;import org.springframework.security.core.userdetails.UserDetails;import java.util.Collection;import java.util.Set;@Datapublic class SecurityUser implements UserDetails {        private Long userId;        private String username;        private Long deptId;        private String password;        private Boolean enabled;        private Collection authorities;        private Set permissions;    public SecurityUser() {    }    @Override    public Collection getAuthorities() {        return this.authorities;    }    @Override    public String getPassword() {        return this.password;    }    @Override    public String getUsername() {        return this.username;    }        @JSONField(serialize = false)    @Override    public boolean isAccountNonExpired() {        return true;    }        @Override    public boolean isAccountNonLocked() {        return true;    }        @Override    public boolean isCredentialsNonExpired() {        return true;    }        @Override    public boolean isEnabled() {        return this.enabled;    }}

auth2获取Token返回信息封装

package com.example.health.model.dto;import lombok.Builder;import lombok.Data;import lombok.EqualsAndHashCode;@Data@EqualsAndHashCode(callSuper = false)@Builderpublic class Oauth2TokenDto {        private String token;        private String refreshToken;        private String tokenHead;        private int expiresIn;}

添加UserServiceImpl实现UserDetailsService接口,用于加载用户信息:

package com.example.health.security.handle;import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;import com.example.health.common.constant.MessageConstant;import com.example.health.mapper.SysUserMapper;import com.example.health.model.SecurityUser;import com.example.health.model.entity.SysUser;import org.springframework.beans.BeanUtils;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.security.core.userdetails.UserDetails;import org.springframework.security.core.userdetails.UserDetailsService;import org.springframework.security.core.userdetails.UsernameNotFoundException;import org.springframework.stereotype.Service;import java.util.Objects;@Servicepublic class UserServiceImpl implements UserDetailsService {    @Autowired    private SysUserMapper sysUserMapper;    @Override    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {        SysUser sysUser = sysUserMapper.selectOne(new QueryWrapper().lambda().eq(SysUser::getUserName, username));        if (Objects.isNull(sysUser)) {            throw new UsernameNotFoundException(MessageConstant.USERNAME_PASSWORD_ERROR);        }        SecurityUser securityUser = new SecurityUser();        BeanUtils.copyProperties(sysUser, securityUser);        securityUser.setEnabled(!Objects.equals(0, sysUser.getStatus()));        return securityUser;    }}

添加AuthenticationEntryPointImpl实现AuthenticationEntryPoint接口,用于处理失败处理类 :

@Componentpublic class AuthenticationEntryPointImpl implements AuthenticationEntryPoint, Serializable {    private static final long serialVersionUID = -8970718410437077606L;    @Override    public void commence(httpservletRequest request, HttpServletResponse response, AuthenticationException authException) throws IOException, ServletException {        int code = HttpStatus.UNAUTHORIZED;        String msg = String.fORMat("请求访问:%s,认证失败,无法访问系统资源", request.getRequestURI());        ServletUtils.renderString(response, JSON.toJSONString(ResultUtils.error(code, msg)));    }}

配置JWT内容增强器

@Componentpublic class JwtTokenEnhancer implements TokenEnhancer {    @Override    public OAuth2AccessToken enhance(OAuth2AccessToken accessToken, OAuth2Authentication authentication) {        SecurityUser securityUser = (SecurityUser) authentication.getPrincipal();        Map info = new HashMap<>();        //把用户ID设置到JWT中        info.put("user_id", securityUser.getUserId());        ((DefaultOAuth2AccessToken) accessToken).setAdditionalInformation(info);        return accessToken;    }}

添加认证服务器配置,使用@EnableAuthorizationServer注解开启:

@AllArgsConstructor@Configuration@EnableAuthorizationServerpublic class Oauth2Config extends AuthorizationServerConfigurerAdapter {    private PasswordEncoder passwordEncoder;    private UserServiceImpl userDetailsService;        private AuthenticationManager authenticationManager;    private JwtTokenEnhancer jwtTokenEnhancer;    @Override    public void configure(ClientDetailsServiceConfigurer clients) throws Exception {        clients.inMemory()                .withClient("client-app")                .secret(passwordEncoder.encode("123456"))                .scopes("all")                .authorizedGrantTypes("password", "refresh_token")                .accessTokenValiditySeconds(3600)                .refreshTokenValiditySeconds(86400);    }    @Override    public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception {        TokenEnhancerChain enhancerChain = new TokenEnhancerChain();        List delegates = new ArrayList<>();        delegates.add(jwtTokenEnhancer);        delegates.add(accessTokenConverter());        enhancerChain.setTokenEnhancers(delegates); //配置JWT的内容增强器        endpoints.authenticationManager(authenticationManager)                .userDetailsService(userDetailsService) //配置加载用户信息的服务                .accessTokenConverter(accessTokenConverter())                .tokenEnhancer(enhancerChain);    }    @Override    public void configure(AuthorizationServerSecurityConfigurer security) throws Exception {        security.allowFormAuthenticationForClients();    }    @Bean    public JwtAccessTokenConverter accessTokenConverter() {        JwtAccessTokenConverter jwtAccessTokenConverter = new JwtAccessTokenConverter();        jwtAccessTokenConverter.seTKEyPair(keyPair());        return jwtAccessTokenConverter;    }    @Bean    public KeyPair keyPair() {        //从classpath下的证书中获取秘钥对        KeyStoreKeyFactory keyStoreKeyFactory = new KeyStoreKeyFactory(new ClassPathResource("jwt.jks"), "123456".toCharArray());        return keyStoreKeyFactory.getKeyPair("jwt", "123456".toCharArray());    }}

添加SpringSecurity配置,允许认证相关路径的访问及表单登录:

@Configuration@EnableWebSecuritypublic class SecurityConfig extends WebSecurityConfigurerAdapter {        @Autowired    private AuthenticationEntryPointImpl unauthorizedHandler;    @Bean    @Override    public AuthenticationManager authenticationManagerBean() throws Exception {        return super.authenticationManagerBean();    }        @Override    protected void configure(HttpSecurity httpSecurity) throws Exception {        httpSecurity                // CSRF禁用,因为不使用session                .csrf().disable()                // 禁用HTTP响应标头                .headers().cacheControl().disable().and()                // 认证失败处理类                .exceptionHandling().authenticationEntryPoint(unauthorizedHandler).and()                // 基于token,所以不需要session                .sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS).and()                // 过滤请求                .authorizeRequests()                // 对于登录login 注册reGISter 验证码captchaImage 允许匿名访问                .antMatchers("/login", "/register", "/captchaImage").permitAll()                .antMatchers("/all*.html", "*.CSS", "*.js", "/profileapi-docs", "/druid@RestController@RequestMapping("/oauth")public class AuthController {    @Autowired    private TokenEndpoint tokenEndpoint;        @RequestMapping(value = "/token", method = RequestMethod.POST)    public BaseResponse postAccessToken(Principal principal, @RequestParam Map parameters) throws HttpRequestMethodNotSupportedException, HttpRequestMethodNotSupportedException {        OAuth2AccessToken oAuth2AccessToken = tokenEndpoint.postAccessToken(principal, parameters).getBody();        Oauth2TokenDto oauth2TokenDto = Oauth2TokenDto.builder()                .token(oAuth2AccessToken.getValue())                .refreshToken(oAuth2AccessToken.getRefreshToken().getValue())                .expiresIn(oAuth2AccessToken.getExpiresIn())                .tokenHead("Bearer ").build();        return ResultUtils.success(oauth2TokenDto);    }}
@RestController@RequestMapping("/all")public class AllController {    @GetMapping(value = "/getStr")    public BaseResponse getStr() {        return ResultUtils.success(“All”);    }}
@RestController@RequestMapping("/test")public class TestController {    @GetMapping(value = "/getStr")    public BaseResponse getStr()  {        return ResultUtils.success("test");    }}

测试使用password授权方式

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

来源地址:https://blog.csdn.net/qq_45072555/article/details/128698253

--结束END--

本文标题: springboot整合springsecurity+oauth2.0密码授权模式

本文链接: https://www.lsjlt.com/news/374361.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

本篇文章演示代码以及资料文档资料下载

下载Word文档到电脑,方便收藏和打印~

下载Word文档
猜你喜欢
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作