spring-boot集成spring-security的oauth2實現(xiàn)github登錄網(wǎng)站的示例
spring-security 里自帶了oauth2,正好YIIU里也用到了spring-security做權(quán)限部分,那為何不直接集成上第三方登錄呢?
然后我開始了折騰
注意:本篇只折騰了spring-security oauth2的客戶端部分,spring-security還可以搭建標(biāo)準的oauth2服務(wù)端
引入依賴
<dependency> <groupId>org.springframework.security.oauth</groupId> <artifactId>spring-security-oauth2</artifactId> </dependency>
添加配置
security:
oauth2:
client:
client-id:
client-secret:
accessTokenUri: https://github.com/login/oauth/access_token
userAuthorizationUri: https://github.com/login/oauth/authorize
clientAuthenticationScheme: form
registered-redirect-uri: ${site.baseUrl}/github_login
use-current-uri: false
resource:
userInfoUri: https://api.github.com/user
sso:
login-path: /github_login
在啟動類上加上注解 @EnableOAuth2Sso 一個注解搞定一切
注意:
- github上的申請應(yīng)用,這里不多說,要注意的是github上要填的回調(diào)地址是跟上面配置的
registered-redirect-uri一樣的 - 加上
@EnableOAuth2Sso注解后,原來系統(tǒng)里配置的/login就默認成了oauth2登錄的路由了,這里通過配置security.oauth2.sso.login-path更改了
保存登錄用戶
注解 @EnableOAuth2Sso 登錄成功了,會把用戶信息寫入到內(nèi)存,還是跟session生命周期一樣的,session沒了,它就沒了, 所以既然登錄成功了,就要保存到數(shù)據(jù)庫里,而且也可以跟本地用戶做關(guān)聯(lián),登錄成功了,直接讀取用戶的權(quán)限信息
保存用戶登錄信息,只要實現(xiàn)一個接口就可以了,在oauth2授權(quán)成功了,它會回調(diào)這個接口的,上代碼
這個類放哪都可以,只要能被spring管理就行
@Bean
public PrincipalExtractor principalExtractor() {
return map -> {
String login = map.get("login").toString();//github的登錄名
GithubUser githubUser = githubUserService.findByLogin(login);
User user;
if (githubUser == null) {
githubUser = new GithubUser();
githubUser = githubUserService.convert(map, githubUser);
//創(chuàng)建一個本地用戶
user = userService.findByUsername(login);
if (user == null) {
user = new User();
user.setUsername(login);
} else {
user.setUsername(login + "_" + githubUser.getGithubId());
}
user.setEmail(githubUser.getEmail());
user.setBio(githubUser.getBio());
user.setUrl(githubUser.getHtml_url());
user.setPassword(new BCryptPasswordEncoder().encode(StrUtil.randomString(16)));
user.setInTime(new Date());
user.setBlock(false);
user.setToken(UUID.randomUUID().toString());
user.setAvatar(githubUser.getAvatar_url());
user.setAttempts(0);
user.setScore(2000);// first register score 2000
user.setSpaceSize(siteConfig.getUserUploadSpaceSize());
user.setGithubUser(githubUser);
// set user's role
Role role = roleService.findById(3); // normal user
Set roles = new HashSet();
roles.add(role);
user.setRoles(roles);
userService.save(user);
} else {
githubUser = githubUserService.convert(map, githubUser);
user = githubUser.getUser();
githubUserService.save(githubUser);
}
//加載用戶的權(quán)限信息
return yiiuUserDetailService.loadUserByUsername(user.getUsername());
};
}
上面 yiiuUserDetailService.loadUserByUsername(user.getUsername()) 這段代碼見下面,就是spring-security的加載用戶權(quán)限代碼
@Service
public class YiiuUserDetailService implements UserDetailsService {
private Logger log = Logger.getLogger(YiiuUserDetailService.class);
@Autowired
private UserService userService;
@Autowired
private PermissionService permissionService;
public UserDetails loadUserByUsername(String username) {
User user = userService.findByUsername(username);
if (user != null) {
List<Permission> permissions = permissionService.findByAdminUserId(user.getId());
List<GrantedAuthority> grantedAuthorities = new ArrayList<>();
for (Permission permission : permissions) {
GrantedAuthority grantedAuthority = new SimpleGrantedAuthority(permission.getName());
grantedAuthorities.add(grantedAuthority);
}
return new org.springframework.security.core.userdetails.User(user.getUsername(), user.getPassword(),
true, true, true, !user.isBlock(), grantedAuthorities);
} else {
log.info("用戶" + username + " 不存在");
throw new UsernameNotFoundException("用戶名或密碼不正確");
}
}
}
參考
代碼詳見:https://github.com/yiiu-co/yiiu
以上就是本文的全部內(nèi)容,希望對大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
使用SpringBoot+AOP實現(xiàn)可插拔式日志的示例代碼
這篇文章主要介紹了使用SpringBoot+AOP實現(xiàn)可插拔式日志的示例代碼,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2019-07-07
Java中使用ForkJoinPool的實現(xiàn)示例
ForkJoinPool是一個功能強大的Java類,用于處理計算密集型任務(wù),本文主要介紹了Java中使用ForkJoinPool的實現(xiàn)示例,具有一定的參考價值,感興趣的可以了解一下2023-09-09
SpringBoot原生組件注入實現(xiàn)兩種方式介紹
SpringBoot是Spring全家桶的成員之一,基于約定優(yōu)于配置的思想(即有約定默認值,在不配置的情況下會使用默認值,在配置文件下配置的話會使用配置的值)。SpringBoot是一種整合Spring技術(shù)棧的方式(或者說是框架),同時也是簡化Spring的一種快速開發(fā)的腳手架2022-10-10

