gpt4 book ai didi

java - 如何使用 spring security 和 spring boot 以 mongoDB 作为存储库来验证 Google 用户?

转载 作者:行者123 更新时间:2023-12-01 15:54:57 25 4
gpt4 key购买 nike

我是 Spring 的新手。我正在使用 spring boot 以利用一些预定义的配置。好像有点用。

在超过 2 周的时间里,我一直坚持使用 spring security 创建身份验证和授权。我想使用 Google 用户进行身份验证。我使用 MongoDB 作为数据存储。

这是我与 Google 用户联系的代码,

<强>1。 SocialConnectionConfiguration.java

package com.example.social;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.social.google.connect.GoogleConnectionFactory;

@Configuration
public class SocialConnectionConfiguration {

// Google Application Credentials
private static final String GoogleClientID = "<clientID>";
private static final String GoogleClientSecret = "<clientSecret>";

@Bean
public GoogleConnectionFactory getGoogleConnectionFactory() {
GoogleConnectionFactory connectionFactory =
new GoogleConnectionFactory(GoogleClientID, GoogleClientSecret);
return connectionFactory;
}

}

<强>2。 SocialConnectionConfiguration.java

package com.example.social;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.social.google.connect.GoogleConnectionFactory;

@Configuration
public class SocialConnectConfiguration{

@Autowired
GoogleConnectionFactory gplusConnectionFactory;

@Bean
public GoogleAPI getGoogleAPI(){
GoogleAPI googleAPI = new GoogleAPI(gplusConnectionFactory);
return googleAPI;
}
}

<强>3。 GoogleAPI.java

package com.example.social;

import org.springframework.social.connect.Connection;
import org.springframework.social.google.api.Google;
import org.springframework.social.google.connect.GoogleConnectionFactory;
import org.springframework.social.oauth2.AccessGrant;
import org.springframework.social.oauth2.GrantType;
import org.springframework.social.oauth2.OAuth2Parameters;

public class GoogleAPI {

private GoogleConnectionFactory GplusConnectionFactory;
private Google google;
private static final String REDIRECT_URI = "http://localhost:8080/google_response";

public Google getGoogle() {
return google;
}

public GoogleAPI(GoogleConnectionFactory GplusConnectionFactory) {
this.GplusConnectionFactory = GplusConnectionFactory;
}

public String getRedirectURI() {

OAuth2Parameters params = new OAuth2Parameters();
params.setRedirectUri(REDIRECT_URI);
params.setScope("profile");
params.setScope("openid");
params.setScope("email");
String authorizeUrl = GplusConnectionFactory.getOAuthOperations().buildAuthorizeUrl(GrantType.AUTHORIZATION_CODE, params);
return authorizeUrl;

}

public Google establishFacebookConnection(String accessToken) {
AccessGrant accessGrant = GplusConnectionFactory.getOAuthOperations().exchangeForAccess(accessToken,REDIRECT_URI, null);
Connection<Google> connection = GplusConnectionFactory.createConnection(accessGrant);
google = connection.getApi();
return google;
}

public boolean isAuthorized() {
if(google != null){
return google.isAuthorized();
}
return false;
}
}

以上三个文件是用来连接google的。但是我怎样才能使用相同的代码进行身份验证。

因为我已经经历了this tutorial (Follow Tutorial-1,2,3) .我发现了一些我们应该知道的信息(在下面),

所以我创建了以下类:

  1. 实体模型
  2. 数据存储库
  3. 商务服务
  4. 用户详细信息服务
  5. 身份验证提供者
  6. 安全配置

1.a) 实体模型 (UserAccount.java)

package com.example.model;

import java.util.Set;

import javax.validation.constraints.NotNull;

import org.bson.types.ObjectId;
import org.springframework.data.annotation.Id;
import org.springframework.data.annotation.PersistenceConstructor;
import org.springframework.data.mongodb.core.index.Indexed;
import org.springframework.data.mongodb.core.mapping.Document;

@Document(collection="user_account")
public class UserAccount {

@Id
private ObjectId id;

private String firstName;

@Indexed
private String lastName;

private Integer age;

@Indexed
@NotNull
private final String username;

@NotNull
private String password;

@NotNull
private boolean enabled = true;

@NotNull
private boolean credentialsexpired = false;

@NotNull
private boolean expired = false;

@NotNull
private boolean locked = false;

private Set<Role> roles;

@PersistenceConstructor
public UserAccount(String username, String firstName, String lastName, Integer age) {
this.username = username;
this.firstName = firstName;
this.lastName = lastName;
this.age = age;
}


public ObjectId getId() {
return id;
}

public String getFirstName() {
return firstName;
}

public void setFirstName(String firstName) {
this.firstName = firstName;
}

public String getLastName() {
return lastName;
}

public void setLastName(String lastName) {
this.lastName = lastName;
}

public Integer getAge() {
return age;
}

public void setAge(Integer age) {
this.age = age;
}

public String getUsername() {
return username;
}

public String getPassword() {
return password;
}

public void setPassword(String password) {
this.password = password;
}

public boolean isEnabled() {
return enabled;
}

public void setEnabled(boolean enabled) {
this.enabled = enabled;
}

public boolean isCredentialsexpired() {
return credentialsexpired;
}

public void setCredentialsexpired(boolean credentialsexpired) {
this.credentialsexpired = credentialsexpired;
}

public boolean isExpired() {
return expired;
}

public void setExpired(boolean expired) {
this.expired = expired;
}

public boolean isLocked() {
return locked;
}

public void setLocked(boolean locked) {
this.locked = locked;
}

public Set<Role> getRoles() {
return roles;
}

public void setRoles(Set<Role> roles) {
this.roles = roles;
}

@Override
public String toString() {
return "[" + this.getId() +
" : " + this.getUsername() +
" : " + this.firstName +
" : " + this.getLastName() +
" : " + this.getAge().toString()+"]";
}

}

1.b)实体模型(Role.java)

package com.example.model;

import javax.validation.constraints.NotNull;

public class Role {

private static final String ADMIN = "ADMIN";
private static final String MANAGER = "MANAGER";
private static final String USER = "USER";

@NotNull
private String code;

@NotNull
private String label;

public Role() {

}

public Role(String code) {
this.code = code;
assignRole(code);
}

private void assignRole(String code) {
if(code.equals("1")) {
this.label = ADMIN;
}
else if(code.equals("2")) {
this.label = MANAGER;
}
else if(code.equals("3")) {
this.label = USER;
}

}

public String getCode() {
return code;
}

public void setCode(String code) {
this.code = code;
}

public String getLabel() {
return label;
}

public void setLabel(String label) {
this.label = label;
}

}

<强>2。数据存储库(UserAccountRepository.java)

package com.example.repository;

import java.io.Serializable;

import org.bson.types.ObjectId;
import org.springframework.data.mongodb.repository.MongoRepository;
import org.springframework.stereotype.Repository;

import com.example.model.UserAccount;

@Repository
public interface UserAccountRepository extends MongoRepository<UserAccount, Serializable> {

public UserAccount findById(ObjectId id);

public UserAccount findByUsername(String username);

}

3.a) UserDteailsS​​ervice(UserAccountDetailsS​​ervice.java)

package com.example.secutiry;

import java.util.ArrayList;
import java.util.Collection;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.userdetails.User;
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 com.example.model.Role;
import com.example.model.UserAccount;
import com.example.service.UserAccountService;

@Service
public class UserAccountDetailsService implements UserDetailsService{

@Autowired
private UserAccountService userService;

@Override
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {

UserAccount user = userService.findByUsername(username);

if(user == null) {
throw new UsernameNotFoundException("Given user name doesn't match !");
}

Collection<GrantedAuthority> grantedAuthorities = new ArrayList<GrantedAuthority>();

for (Role role : user.getRoles()) {
grantedAuthorities.add(new SimpleGrantedAuthority(role.getLabel()));
}

User userDetails = new User(user.getUsername(),
user.getPassword(),user.isEnabled(),
user.isExpired(),user.isCredentialsexpired(),
user.isLocked(), grantedAuthorities);

return userDetails;
}

}

3.b) UserDteailsS​​ervice(UserAccountService.java)

package com.example.service;

import java.io.Serializable;
import java.util.List;

import org.bson.types.ObjectId;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.stereotype.Service;

import com.example.model.UserAccount;
import com.example.repository.UserAccountRepository;

@Service
public class UserAccountService implements UserAccountRepository {

@Autowired
private UserAccountRepository repository;

@Override
public <S extends UserAccount> List<S> save(Iterable<S> entites) {
// TODO Auto-generated method stub
return null;
}

@Override
public List<UserAccount> findAll() {
// TODO Auto-generated method stub
return null;
}

@Override
public List<UserAccount> findAll(Sort sort) {
// TODO Auto-generated method stub
return null;
}

@Override
public <S extends UserAccount> S insert(S entity) {
// TODO Auto-generated method stub
return null;
}

@Override
public <S extends UserAccount> List<S> insert(Iterable<S> entities) {
// TODO Auto-generated method stub
return null;
}

@Override
public Page<UserAccount> findAll(Pageable pageable) {
// TODO Auto-generated method stub
return null;
}

@Override
public <S extends UserAccount> S save(S entity) {
repository.save(entity);
return null;
}

@Override
public UserAccount findOne(Serializable id) {
// TODO Auto-generated method stub
return null;
}

@Override
public boolean exists(Serializable id) {
// TODO Auto-generated method stub
return false;
}

@Override
public Iterable<UserAccount> findAll(Iterable<Serializable> ids) {
// TODO Auto-generated method stub
return null;
}

@Override
public long count() {
// TODO Auto-generated method stub
return 0;
}

@Override
public void delete(Serializable id) {
// TODO Auto-generated method stub

}

@Override
public void delete(UserAccount entity) {
// TODO Auto-generated method stub

}

@Override
public void delete(Iterable<? extends UserAccount> entities) {
// TODO Auto-generated method stub

}

@Override
public void deleteAll() {
// TODO Auto-generated method stub

}

@Override
public UserAccount findById(ObjectId id) {
UserAccount user = repository.findById(id);
return user;
}

@Override
public UserAccount findByUsername(String username) {
UserAccount user = repository.findByUsername(username);
return user;
}

}

<强>4。身份验证提供程序(UserAccountAuthenticationProvider.java)

package com.example.secutiry;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.authentication.BadCredentialsException;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.authentication.dao.AbstractUserDetailsAuthenticationProvider;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Component;

@Component
public class UserAccountAuthenticationProvider extends AbstractUserDetailsAuthenticationProvider {

@Autowired
private UserAccountDetailsService userDetailsService;

@Autowired
private PasswordEncoder passwordEncoder;

@Override
protected void additionalAuthenticationChecks(UserDetails userDetails,
UsernamePasswordAuthenticationToken token)
throws AuthenticationException {

if(token.getCredentials() == null
|| userDetails.getPassword() == null) {
throw new BadCredentialsException("Credentials may not be Empty!");
}

if(!passwordEncoder.matches(token.getCredentials().toString(),
userDetails.getPassword())) {
throw new BadCredentialsException("Invalid Credentials !");
}

}

@Override
protected UserDetails retrieveUser(String username,
UsernamePasswordAuthenticationToken authentication)
throws AuthenticationException {
UserDetails userDetails = userDetailsService.loadUserByUsername(username);

return userDetails;
}

}

<强>5。安全配置(SecurityConfiguration.java)

package com.example;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.annotation.Order;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.config.http.SessionCreationPolicy;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;

import com.example.secutiry.UserAccountAuthenticationProvider;

@Configuration
@EnableWebSecurity
public class SecurityConfiguration {

@Autowired
private UserAccountAuthenticationProvider userAccountAuthenticationProvider;

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

@Autowired
public void configureGlobal(AuthenticationManagerBuilder auth) {
auth.authenticationProvider(userAccountAuthenticationProvider);
}

@Configuration
@Order(1)
public static class ApiWebSecurityConfigurationAdapter
extends WebSecurityConfigurerAdapter{

@Override
protected void configure(HttpSecurity http) throws Exception {

http
.antMatcher("/**")
.authorizeRequests()
.anyRequest().hasRole("USER")
.and()
.httpBasic()
.and()
.sessionManagement()
.sessionCreationPolicy(SessionCreationPolicy.STATELESS);
}
}
}

所以现在,如果我单独使用 Google 连接代码,我就可以连接到 google。很好,但我如何使用 Google 连接代码进行身份验证?

如果我的代码有误,请纠正我,如果我想包含或排除任何行或文件,请指导我,因为我是 spring 的新手。

提前致谢

最佳答案

为什么要在自己的 UserDetailsS​​ervice 实现中再次检查密码?

if(token.getCredentials() == null
|| userDetails.getPassword() == null) {
throw new BadCredentialsException("Credentials may not be Empty!");
}
if(!passwordEncoder.matches(token.getCredentials().toString(),
userDetails.getPassword())) {
throw new BadCredentialsException("Invalid Credentials !");
}

密码检查仅由谷歌身份提供商完成。所以你永远不会得到密码。你已经检查过了吗http://gabiaxel.github.io/spring-social-google-reference/connecting.htmlhttp://docs.spring.io/spring-social/docs/1.1.x/reference/htmlsingle/#enabling-provider-sign-in-with-code-socialauthenticationfilter-code

关于java - 如何使用 spring security 和 spring boot 以 mongoDB 作为存储库来验证 Google 用户?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34287655/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com