联系我们 - 广告服务 - 联系电话:
您的当前位置: > 综合 > > 正文

焦点讯息:spring-security-oauth2是什么?OAuth2与spring-security-oauth2

来源:CSDN 时间:2023-01-16 08:22:42

OAuth2与spring-security-oauth2


(资料图)

OAuth2OAuth2是什么OAuth2中4种授权模式作用场景 spring-security-oauth2spring-security-oauth2是什么搭建spring-security-oauth2案例环境版本pom.xmlapplication.yml 目录结构密码模式获取token访问受保护的资源 授权码模式获取code获取token访问受保护的资源 结语

OAuth2

OAuth2是什么

关于这块概念可以参考: https://www.jianshu.com/p/84a4b4a1e833

OAuth2中4种授权模式作用场景

授权码模式 授权码模式一般用于提供给第三方使用简化模式 简化模式一般不会使用密码模式 密码模式一般仅用于系统内部使用客户端凭证模式 客户端凭证模式一般不会使用

spring-security-oauth2

spring-security-oauth2是什么

spring-security-oauth2是基于spring-security框架完整实现oauth2协议的框架,具有oauth2中4种模式访问和第三方登录等功能。

搭建spring-security-oauth2案例

环境版本

1.8Hoxton.SR92.3.0.RELEASE8.0.15

pom.xml

org.springframework.bootspring-boot-starter-weborg.springframework.bootspring-boot-starter-testorg.springframework.bootspring-boot-starter-jdbcorg.springframework.cloudspring-cloud-starter-securityorg.springframework.cloudspring-cloud-starter-oauth2org.springframework.securityspring-security-jwt1.1.0.RELEASEmysqlmysql-connector-java${mysql.connector.version}org.springframework.bootspring-boot-starter-data-redisorg.projectlomboklombokorg.springframework.bootspring-boot-dependencies${spring.boot.version}pomimportorg.springframework.cloudspring-cloud-dependencies${spring.cloud.version}pomimport

application.yml

server:  port: 8080spring:  datasource:    url: jdbc:mysql://192.168.174.129:3306/oauth?serverTimezone=GMT%2B8&characterEncoding=utf-8&autoReconnect=true&allowMultiQueries=true    username: root    password: 123456    driver-class-name: com.mysql.cj.jdbc.Driver

目录结构

DemoAuthorizationServerConfiguration:授权服务配置

@Configuration@EnableAuthorizationServer@AllArgsConstructorpublic class DemoAuthorizationServerConfiguration extends AuthorizationServerConfigurerAdapter {private DataSource dataSource;private TokenStore tokenStore;private AuthenticationManager authenticationManager;private UserDetailsService userDetailsService;private TokenEnhancer tokenEnhancer;private JwtAccessTokenConverter jwtAccessTokenConverter;@Overridepublic void configure(ClientDetailsServiceConfigurer clients) throws Exception {// @formatter:offclients.inMemory().withClient("test-client").secret("$2a$08$YGw560YLRWHg3Hl29ZlmdOfAeyRQ2u0kDiqUyQ62Y1pkW5n4a.hjO").authorizedGrantTypes("password", "authorization_code", "refresh_token", "implicit").authorities("ROLE_CLIENT").redirectUris("http://localhost:8084/oauth/callback").scopes("read", "write", "all");// 请求参数scope必须为集合中的某个值// @formatter:on}@Overridepublic void configure(AuthorizationServerSecurityConfigurer security) throws Exception {// 允许表单传参client信息security.allowFormAuthenticationForClients().tokenKeyAccess("permitAll()").checkTokenAccess("isAuthenticated()");}@Overridepublic void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception {endpoints.tokenStore(tokenStore).authenticationManager(authenticationManager).userDetailsService(userDetailsService).tokenEnhancer(tokenEnhancer).accessTokenConverter(jwtAccessTokenConverter);}}

DemoJwtTokenStoreConfiguration:JwtToken仓库配置

@Configurationpublic class DemoJwtTokenStoreConfiguration {@Beanpublic TokenStore tokenStore(JwtAccessTokenConverter tokenConverter) {return new JwtTokenStore(tokenConverter);}@Beanpublic JwtAccessTokenConverter tokenConverter() {JwtAccessTokenConverter tokenConverter = new JwtAccessTokenConverter();tokenConverter.setSigningKey("abc");return tokenConverter;}@Beanpublic TokenEnhancer tokenEnhancer(JwtAccessTokenConverter tokenConverter) {return new DemoJwtTokenEnhancer(tokenConverter);}}

DemoResourceServerConfiguration:资源服务配置

@Configuration@EnableResourceServer@AllArgsConstructorpublic class DemoResourceServerConfiguration extends ResourceServerConfigurerAdapter {private AccessDeniedHandler accessDeniedHandler;//private AuthenticationEntryPoint authenticationEntryPoint;@Overridepublic void configure(HttpSecurity http) throws Exception {http.authorizeRequests().anyRequest().authenticated().and().exceptionHandling().accessDeniedHandler(accessDeniedHandler)//.authenticationEntryPoint(authenticationEntryPoint).and().csrf().disable();}@Overridepublic void configure(ResourceServerSecurityConfigurer resources) throws Exception {super.configure(resources);}}

DemoWebSecurityConfiguration:WebSecurity配置

@Configurationpublic class DemoWebSecurityConfiguration extends WebSecurityConfigurerAdapter {@Bean@Override@SneakyThrowspublic AuthenticationManager authenticationManagerBean() {return super.authenticationManagerBean();}@Beanpublic PasswordEncoder passwordEncoder() {return new BCryptPasswordEncoder(BCryptPasswordEncoder.BCryptVersion.$2A, 8);}@Overrideprotected void configure(HttpSecurity http) throws Exception {http.httpBasic().and().csrf().disable();}}

DemoController:受保护的Controller资源

@RestController@RequestMapping("/api")public class DemoController {@RequestMapping("/test")public Maptest() {Mapresult = new HashMap<>();result.put("time", System.currentTimeMillis());return result;}}

DemoClientDetailsService:ClientDetailsService实现类

public class DemoClientDetailsService extends JdbcClientDetailsService {public DemoClientDetailsService(DataSource dataSource) {super(dataSource);}}

DemoUserDetails:用户信息类

@Getterpublic class DemoUserDetails extends User {/** * 用户id */private String userId;/** * 手机号 */private String mobile;/** * 是否超级管理员 1是 0否 */private Boolean administrator;/** * 角色id */private Listroles;public DemoUserDetails(String userId, String mobile, String username, String password, boolean enabled, Listroles, boolean accountNonExpired,   boolean credentialsNonExpired, boolean accountNonLocked,   Collection authorities, Boolean administrator) {super(username, password, enabled, accountNonExpired, credentialsNonExpired, accountNonLocked,authorities);this.userId = userId;this.roles = roles;this.administrator = administrator;this.mobile = mobile;}}

DemoUserDetailsServiceImpl:UserDetailsService实现类

@Servicepublic class DemoUserDetailsServiceImpl implements UserDetailsService {@Overridepublic UserDetails loadUserByUsername(String s) throws UsernameNotFoundException {return new DemoUserDetails("userId", "mobile", s, "$2a$08$EiGfaup8QkkjT6DhvCSFRuNhdFTEV7Rbu/avUm8lGL2ZUji/lTWji", true, Arrays.asList(1L), true, true, true,AuthorityUtils.commaSeparatedStringToAuthorityList("1,2"), false);}}

DemoAccessDeniedHandler:403处理器

@Componentpublic class DemoAccessDeniedHandler implements AccessDeniedHandler {@Overridepublic void handle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, AccessDeniedException e) throws IOException, ServletException {httpServletResponse.setStatus(HttpServletResponse.SC_FORBIDDEN);httpServletResponse.setContentType("application/json;charset=UTF-8");PrintWriter out = httpServletResponse.getWriter();out.write(new ObjectMapper().writeValueAsString("权限不足,请联系管理员!"));out.flush();out.close();}}

DemoAuthenticationEntryPoint:401处理器

//@Componentpublic class DemoAuthenticationEntryPoint implements AuthenticationEntryPoint {@Overridepublic void commence(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, AuthenticationException e) throws IOException, ServletException {httpServletResponse.setStatus(HttpServletResponse.SC_FORBIDDEN);httpServletResponse.setContentType("application/json;charset=UTF-8");PrintWriter out = httpServletResponse.getWriter();out.write(new ObjectMapper().writeValueAsString("请先登录!"));out.flush();out.close();}}

DemoJwtTokenEnhancer:TokenEnhancer实现类

@AllArgsConstructorpublic class DemoJwtTokenEnhancer implements TokenEnhancer {private JwtAccessTokenConverter jwtAccessTokenConverter;@Overridepublic OAuth2AccessToken enhance(OAuth2AccessToken accessToken, OAuth2Authentication authentication) {DemoUserDetails principal =(DemoUserDetails) authentication.getUserAuthentication().getPrincipal();Mapinfo = new HashMap<>();info.put("user_id", principal.getUserId() == null ? "" : String.valueOf(principal.getUserId()));((DefaultOAuth2AccessToken) accessToken).setAdditionalInformation(info);return jwtAccessTokenConverter.enhance(accessToken, authentication);}}

DemoPasswordEncoder:PasswordEncoder实现类

public class DemoPasswordEncoder implements PasswordEncoder {@Overridepublic String encode(CharSequence rawPassword) {return (String) rawPassword;}@Overridepublic boolean matches(CharSequence rawPassword, String encodedPassword) {return encodedPassword.equals(encode(rawPassword));}}

密码模式

获取token

/oauth/token,获取token,access_token就是我们需要在请求头中携带的token。 访问url: http://localhost:8080/oauth/token?username=admin&password=qwer1234&grant_type=password&scope=all 并在请求头中加入basic auth参数 眼力好的同学已经看出来上图中已经在url中出现了client… 也可以直接访问这个url: http://localhost:8080/oauth/token?username=admin&password=qwer1234&grant_type=password&scope=all&client_id=test-client&client_secret=abc 这种访问方式又是哪里出来的?第一个java代码块里面就有配置了… allowFormAuthenticationForClients又是怎么实现的呢?

@Overridepublic void configure(AuthorizationServerSecurityConfigurer security) throws Exception {// 允许表单传参client信息security.allowFormAuthenticationForClients().tokenKeyAccess("permitAll()").checkTokenAccess("isAuthenticated()");}

访问受保护的资源

访问受保护的资源 图片中就是在请求头中将入key为Authorization的值 Authorization Bearer eyJhbGciOiJ…

授权码模式

获取code

直接在浏览器上访问该链接 http://localhost:8080/oauth/authorize?response_type=code&scope=all&client_id=test-client&client_secret=abc&redirect_uri=http://localhost:8084/oauth/callback

浏览器弹出httpBasic验证 输入预设用户名/密码:admin/qwer1234 点击确定,弹出OAuth2用户授权页面,点击授权Authorize 页面重定向到redirect_uri参数指定的url并附带了code

获取token

使用上一步中获取的code替换下面的,并访问url: http://localhost:8080/oauth/token?grant_type=authorization_code&client_id=test-client&client_secret=abc&redirect_uri=http://localhost:8084/oauth/callback&code=OWwAmR

不会有人直接复制链接不改code参数吧?不会吧,不会吧

访问受保护的资源

该步骤与密码模式中一致

结语

spring-security-oauth2秉承spring一贯风格特色,配置多种多样,如果见到和上面配置不一样很正常,如果想要深入了解,需要仔细阅读源码。上面的案例只是简单的入门描述,由此可以引发很多疑问。

使用数据库配置client与user怎么做需要配置手机号验证码登录等其他方式需要怎么做授权码模式需要用户手动授权,如果特殊情况下改为不需要授权怎么做需要在网关中使用,该怎么做需要权限验证,该怎么做基于spring-security-oauth2框架的单点登录怎么做?

责任编辑:

标签:

相关推荐:

精彩放送:

新闻聚焦
Top