理论
OAuth2是允许应用程序获取对HTTP服务(如GitHub、使用qq登录某网站、使用微信登录某网站等等)上的用户帐户的有限访问权限的授权框架。 它通过将用户身份验证委托给托管用户帐户的服务,并授权第三方应用程序访问用户帐户。 OAuth2为Web和桌面应用程序以及移动设备提供了授权流程。
一、什么是OAuth协议
OAuth(开放授权)是一个开放标准。允许第三方网站在用户授权的前提下访问在用户在服务商那里存储的各种信息。
而这种授权无需将用户提供用户名和密码提供给该第三方网站。
OAuth允许用户提供一个令牌给第三方网站,一个令牌对应一个特定的第三方网站,同时该令牌只能在特定的时间内访问特定的资源。
二、OAuth的原理和授权流程
OAuth的认证和授权的过程中涉及的三方包括:
服务商:
用户使用服务的提供方,一般用来存消息、储照片、视频、联系人、文件等(比如Twitter、Sina等)。
用 户:
服务商的用户
第三方:
通常是网站,该网站想要访问用户存储在服务商那里的信息。比如某个提供照片打印服务的网站,用户想在那里打印自己存在服务商那里的网络相册。在认证过程之前,第三方需要先向服务商申请第三方服务的唯一标识。
三、实例案例
基本上现在的互联网站都会提供开放授权。
以及公司内部的boss系统 统一账号登录 等等,都是类似的open auth标准。
四、OAuth认证和授权的过程
实战
一、代码
好,不说理论了,现在我们开始使用spring cloud oauth2创建一个认证服务吧。
新建项目:
引入依赖:
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-oauth2</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>com.h2database</groupId>
<artifactId>h2</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
Account
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</dependency>
@Data
@NoArgsConstructor
@AllArgsConstructor
@Entity
class Account {
public Account(String username, String password, boolean active) {
this.username = username;
this.password = password;
this.active = active;
}
@Id
@GeneratedValue
private Long id;
private String username, password;
private boolean active;
}
AccountRepository
interface AccountRepository extends JpaRepository<Account, Long> {
Optional<Account> findByUsername(String username);
}
AccountUserDetailsService
@Service
class AccountUserDetailsService implements UserDetailsService {
private final AccountRepository accountRepository;
public AccountUserDetailsService(AccountRepository accountRepository) {
this.accountRepository = accountRepository;
}
@Override
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
return accountRepository.findByUsername(username)
.map(account -> new User(account.getUsername(),
account.getPassword(), account.isActive(), account.isActive(), account.isActive(), account.isActive(),
AuthorityUtils.createAuthorityList("ROLE_ADMIN", "ROLE_USER")
))
.orElseThrow(() -> new UsernameNotFoundException("couldn't find the username " + username + "!"));
}
}
AuthServiceConfiguration
@Configuration
@EnableAuthorizationServer
class AuthServiceConfiguration extends AuthorizationServerConfigurerAdapter {
private final AuthenticationManager authenticationManager ;
AuthServiceConfiguration(AuthenticationManager authenticationManager) {
this.authenticationManager = authenticationManager;
}
@Override
public void configure(ClientDetailsServiceConfigurer clients) throws Exception {
clients
.inMemory()
.withClient("html5")
.secret("password")
.authorizedGrantTypes("password")
.scopes("openid");
}
@Override
public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception {
endpoints.authenticationManager( this.authenticationManager);
}
}
AuthServiceApplication
@SpringBootApplication
@RestController
public class AuthServiceApplication {
@Bean
CommandLineRunner demo(AccountRepository accountRepository) {
return args ->
Stream.of("hezhuofan,spring", "zhangsan,cloud", "lisi,boot", "wangmazi,security")
.map(tpl -> tpl.split(","))
.forEach(tpl -> accountRepository.save(new Account(tpl[0], tpl[1], true)));
}
public static void main(String[] args) {
SpringApplication.run(AuthServiceApplication.class, args);
}
}
application.properties:
spring.application.name=auth-service
server.port=9191
server.contextPath=/uaa
security.sessions=if_required
二、模拟请求
使用Postman来模拟请求:
authorization:
headers:
token:
{
"access_token": "67692d8f-49d5-440e-a332-22353e440a5b",
"token_type": "bearer",
"expires_in": 43199,
"scope": "openid"
}
总结
在微服务中,你可以使用oauth认证流程来保护一些需要保护rest api。在公司内部的统一账户登录认证中,也可以通过oauth的方式为要想要接入登录验证的内部项目提供统一登录入口。在互联网上,你也构建自己oauth认证server向第三方应用提供经过用户授权的用户资料。就写这么多,oauth认证中的概念写得不是很详细,以后有机会再专门涉及。
附:Postman安装指南
Chrome浏览器 > Apps > WebStore > search Postman
本文分享自 ImportSource 微信公众号,前往查看
如有侵权,请联系 cloudcommunity@tencent.com 删除。
本文参与 腾讯云自媒体同步曝光计划 ,欢迎热爱写作的你一起参与!