Spring Cloud Oauth2 搭建授权认证中心 简化版本不复杂

导读:本篇文章讲解 Spring Cloud Oauth2 搭建授权认证中心 简化版本不复杂,希望对大家有帮助,欢迎收藏,转发!站点地址:www.bmabk.com

1,创建一个springboot项目

我的版本使用的是springboot2.2.1版本

2,在pom文件中加入security和oauth2依赖

<dependency>
	<groupId>org.springframework.cloud</groupId>
	<artifactId>spring-cloud-starter-security</artifactId>
	<optional>true</optional>
</dependency>
<dependency>
	<groupId>org.springframework.cloud</groupId>
	<artifactId>spring-cloud-starter-oauth2</artifactId>
</dependency>
<dependency>
	<groupId>org.springframework.security.oauth</groupId>
	<artifactId>spring-security-oauth2</artifactId>
	<!-- 这里不要使用2.4.0版本, 注解EnableAuthorizationServer在2.4.0版本中是弃用的 -->
	<version>2.3.0.RELEASE</version>
</dependency>
<dependency>
	<groupId>org.springframework.security.oauth.boot</groupId>
	<artifactId>spring-security-oauth2-autoconfigure</artifactId>
</dependency>

3,创建WebSecurityConfigurerAdapter的实现类WebSecurityConfig.java

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;

/**
 *
 * @author lixx
 * @version 1.0
 * @date 2020-05-18 14:19
 */
@Configuration
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {


	@Bean
	public PasswordEncoder passwordEncoder() {
		return new BCryptPasswordEncoder();
	}

	@Override
	protected void configure(HttpSecurity http) throws Exception {
		http.csrf().disable()
				.authorizeRequests()
				.antMatchers("/r/r1").hasAnyAuthority("p1")
				.antMatchers("/login*").permitAll()
				.anyRequest().authenticated()
				.and()
				.formLogin();
	}
}

4,创建授权服务配置类AuthorizationServer.java

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.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.oauth2.config.annotation.configurers.ClientDetailsServiceConfigurer;
import org.springframework.security.oauth2.config.annotation.web.configuration.AuthorizationServerConfigurerAdapter;
import org.springframework.security.oauth2.config.annotation.web.configuration.EnableAuthorizationServer;
import org.springframework.security.oauth2.config.annotation.web.configurers.AuthorizationServerEndpointsConfigurer;
import org.springframework.security.oauth2.config.annotation.web.configurers.AuthorizationServerSecurityConfigurer;
import org.springframework.security.oauth2.provider.ClientDetailsService;
import org.springframework.security.oauth2.provider.code.AuthorizationCodeServices;
import org.springframework.security.oauth2.provider.code.InMemoryAuthorizationCodeServices;
import org.springframework.security.oauth2.provider.token.AuthorizationServerTokenServices;
import org.springframework.security.oauth2.provider.token.DefaultTokenServices;
import org.springframework.security.oauth2.provider.token.TokenStore;

/**
 * 授权服务
 *
 * @author lixx
 * @version 1.0
 * @date 2020-05-18 13:32
 */
@Configuration
@EnableAuthorizationServer
public class AuthorizationServer extends AuthorizationServerConfigurerAdapter {

	/**
	 * 令牌策略
	 */
	@Autowired
	private TokenStore tokenStore;

	/**
	 * 客户端详情服务
	 */
	@Autowired
	private ClientDetailsService clientDetailsService;

	/**
	 * 认证管理器 , 密码模式需要
	 */
	@Autowired
	private AuthenticationManager authenticationManager;

	/**
	 * 授权码模式, 需要
	 */
	@Autowired
	private AuthorizationCodeServices authorizationCodeServices;

	/**
	 * 用来配置客户端详情服务(ClientDetailsService),客户端详情信息在
	 * 这里进行初始化,你能够把客户端详情信息写死在这里或者是通过数据库来存储调取详情信息
	 *
	 * @param clients
	 * @throws Exception
	 */
	@Override
	public void configure(ClientDetailsServiceConfigurer clients) throws Exception {
		clients
				// 使用本地的方式存储, 为了简易方便测试
				.inMemory()
				// 客户端id
				.withClient("c1")
				// 客户端密钥
				.secret(new BCryptPasswordEncoder().encode("secret"))
				// 客户端可以请求的资源列表, id
				.resourceIds("res1")
				// 该客户端允许的授权类型 authorization_code(授权码模式),password(密码模式),refresh_token(刷新令牌),implicit(简化模式),client_credentials(客户端模式)
				.authorizedGrantTypes("authorization_code", "password", "client_credentials", "implicit", "refresh_token")
				// 允许的授权范围
				.scopes("all")
				// false 授权码模式时, 申请授权码时是跳转到授权页面, true 不跳转页面, 直接获取到授权码
				.autoApprove(false)
				//加上验证回调地址
				.redirectUris("http://www.baidu.com");
	}

	/**
	 * 用来配置令牌(token)的访问端点和令牌服务(token services)
	 *
	 * @param endpoints
	 * @throws Exception
	 */
	@Override
	public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception {
		endpoints
				// 认证管理器
				.authenticationManager(authenticationManager)
				// 授权码管理器
				.authorizationCodeServices(authorizationCodeServices)
				// 令牌管理器
				.tokenServices(tokenServices())
				// 允许post 请求令牌
				.allowedTokenEndpointRequestMethods(HttpMethod.POST);
	}

	/**
	 * 用来配置令牌端点的安全约束
	 *
	 * @param security
	 * @throws Exception
	 */
	@Override
	public void configure(AuthorizationServerSecurityConfigurer security) throws Exception {
		security
				//oauth/token_key是公开
				.tokenKeyAccess("permitAll()")
				//oauth/check_token公开
				.checkTokenAccess("permitAll()")
				//表单认证(申请令牌)
				.allowFormAuthenticationForClients()
		;
	}

	/**
	 * 管理令牌的服务
	 *
	 * @return
	 */
	@Bean
	public AuthorizationServerTokenServices tokenServices() {
		DefaultTokenServices services = new DefaultTokenServices();
		// 客户端详情 服务
		services.setClientDetailsService(clientDetailsService);
		// 是否刷新令牌
		services.setSupportRefreshToken(true);
		// 令牌策略
		services.setTokenStore(tokenStore);
		// 令牌有效期
		services.setAccessTokenValiditySeconds(7200);
		// 刷新令牌时间
		services.setRefreshTokenValiditySeconds(259200);
		return services;
	}

	/**
	 * 授权码服务
	 */
	@Bean
	public AuthorizationCodeServices authorizationCodeServices() {
		return new InMemoryAuthorizationCodeServices();
	}
}

5,AuthorizationServer类中的对象 TokenStore  和 AuthenticationManager 还没有注入到spring容器中

5.1,注入TokenStore bean到spring容器

创建令牌策略配置类TokenConfig.java,

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.oauth2.provider.token.TokenStore;
import org.springframework.security.oauth2.provider.token.store.InMemoryTokenStore;

/**
 * 令牌策略
 *
 * @author lixx
 * @version 1.0
 * @date 2020-05-18 13:48
 */
@Configuration
public class TokenConfig {

	@Bean
	public TokenStore tokenStore() {
		// 本地方式, 简化, 为了方便测试
		return new InMemoryTokenStore();
	}

}

5.2,注入AuthenticationManager到spring容器

在第3步的WebSecurityConfig.java配置类中加入bean

@Bean
@Override
public AuthenticationManager authenticationManagerBean() throws Exception {
	return super.authenticationManagerBean();
}

6,创建UserDetailsService的实现类AuthorizationUserDetailsService.java,UserDetailsService在获取用户信息时用到的

import com.familylinkedu.oauth2.domain.UserDto;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.stereotype.Service;

/**
 *
 * @author lixx
 * @version 1.0
 * @date 2020-05-18 14:06
 */
@Service
public class AuthorizationUserDetailsService implements UserDetailsService {

	@Override
	public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
		UserDto userDto = new UserDto();
		userDto.setId("1");
		userDto.setMobile("10086");
		userDto.setUsername("zhangsan");
		// 密码是 123
		userDto.setPassword("$2a$10$2km83mXcQezJ8v5aAHYoe.QzzmJfOg1gA7F8AU2wI71mlXcPukUJm");
		String encode = new BCryptPasswordEncoder().encode(userDto.getPassword());
		System.err.println(encode);
		// 用户拥有的权限
		List<GrantedAuthority> authorities = new ArrayList<>();
		authorities.add(new SimpleGrantedAuthority("p1"));
		authorities.add(new SimpleGrantedAuthority("p3"));

		userDto.setAuthorities(authorities);
		return userDto;
	}
}

UserDto对象如下:

import lombok.Data;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.userdetails.UserDetails;

import java.util.Collection;

/**
 * @author lixx
 * @version 1.0
 * @date 2020-05-18 14:08
 */
@Data
public class UserDto implements UserDetails {

	private String id;
	private String username;
	private String password;
	private String mobile;

	private List<GrantedAuthority> authorities = new ArrayList<>();

	@Override
	public Collection<? extends GrantedAuthority> getAuthorities() {
		return authorities;
	}

	@Override
	public boolean isAccountNonExpired() {
		return true;
	}

	@Override
	public boolean isAccountNonLocked() {
		return true;
	}

	@Override
	public boolean isCredentialsNonExpired() {
		return true;
	}

	@Override
	public boolean isEnabled() {
		return true;
	}
}

7,启动springboot项目

暴露如下url

Spring Cloud Oauth2 搭建授权认证中心 简化版本不复杂

8,获取授权码,使用浏览器访问 /oauth/authorize 接口申请授权,本章demo接口示例如下:

http://localhost:8900/oauth/authorize?client_id=c1&response_type=code&scope=all&redirect_uri=http://www.baidu.com

效果如下:

Spring Cloud Oauth2 搭建授权认证中心 简化版本不复杂

Spring Cloud Oauth2 搭建授权认证中心 简化版本不复杂

拿到授权码 

Spring Cloud Oauth2 搭建授权认证中心 简化版本不复杂

9,获取令牌, 使用授权码,post的方式访问  /oauth/token 接口

授权码模式:

Spring Cloud Oauth2 搭建授权认证中心 简化版本不复杂

密码模式:(不需要第8步)

Spring Cloud Oauth2 搭建授权认证中心 简化版本不复杂

 客户端模式:(不需要第8步)

Spring Cloud Oauth2 搭建授权认证中心 简化版本不复杂

简化模式:(直接获取到令牌)

Spring Cloud Oauth2 搭建授权认证中心 简化版本不复杂

Spring Cloud Oauth2 搭建授权认证中心 简化版本不复杂

 

 真实案例代码如下微信扫一扫登录、微信支付、springsecurity&oauth2-Java文档类资源-CSDN下载项目中使用到的技术包含SpringBoot、SpringSecurity&oauth2(安全更多下载资源、学习资料请访问CSDN下载频道.Spring Cloud Oauth2 搭建授权认证中心 简化版本不复杂https://download.csdn.net/download/a1053765496/24871993

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/72561.html

(0)
小半的头像小半

相关推荐

极客之音——专业性很强的中文编程技术网站,欢迎收藏到浏览器,订阅我们!