springsecurity自定义userService和认证逻辑(在springboot中)

看了一下感觉这东西还挺难的,得写点什么来总结一下。

1.要启用springsecurity很简单只需要在pom.xml中添加相关依赖就行了

<dependency>
<groupId>org.springframework.boot</groudId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>

2.准备User类和Role类,这里直接用JPA

@Entity(name = "t_user")
public class User implements UserDetails {
   
       
               
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    private String username;

    private String password;

    private boolean accountNonExpired;

    private boolean accountNonLocked;

    private boolean credentialsNonExpired;

    private boolean enabled;

    @ManyToMany(fetch = FetchType.EAGER,cascade = CascadeType.PERSIST)
    private List<Role> roles;



    @Override
    public Collection<? extends GrantedAuthority> getAuthorities() {
   
   
        List<SimpleGrantedAuthority> authorities = new ArrayList<>();
        for(Role role:getRoles()){
   
   
            authorities.add(new SimpleGrantedAuthority(role.getName()));
        }

        return authorities;
        
    }

    @Override
    public String getPassword() {
   
   
        return password;
    }

    @Override
    public String getUsername() {
   
   
        return username;
    }

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

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

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

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

    //下面是基本的getter和setter

    public Long getId() {
   
   
        return id;
    }

    public void setId(Long id) {
   
   
        this.id = id;
    }

    public void setUsername(String username) {
   
   
        this.username = username;
    }

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

    public void setAccountNonExpired(boolean accountNonExpired) {
   
   
        this.accountNonExpired = accountNonExpired;
    }

    public void setAccountNonLocked(boolean accountNonLocked) {
   
   
        this.accountNonLocked = accountNonLocked;
    }

    public void setCredentialsNonExpired(boolean credentialsNonExpired) {
   
   
        this.credentialsNonExpired = credentialsNonExpired;
    }

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

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

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

用户实体类主要需要实现 UserDetails 接口,并实现接口中的方法。

这里的字段基本都好理解,几个特殊的我来稍微说一下:

accountNonExpired、accountNonLocked、credentialsNonExpired、enabled 这四个属性分别用来描述用户的状态,表示账户是否没有过期、账户是否没有被锁定、密码是否没有过期、以及账户是否可用。
roles 属性表示用户的角色,User 和 Role 是多对多关系,用一个 @ManyToMany 注解来描述。
getAuthorities 方法返回用户的角色信息,我们在这个方法中把自己的 Role 稍微转化一下即可。
3.定义UserDao和UserService

public interface UserDao extends JpaRepository<User,Long> {
   
   

    User findUserByUsername(String username);
}

@Service
public class UserService implements UserDetailsService {
   
   
    @Autowired
    UserDao userDao;

    @Override
    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
   
   
        User user = userDao.findUserByUsername(username);
        if(user==null){
   
   
            throw new UsernameNotFoundException("用户不存在");
        }
        return user;
    }
}

4.前端定义了一组页面,分别划归3个不同得权限暂且整三个vip1,vip2,vip3得权限吧
在首页中写了个table并放上三类页面的超链接

<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org"
                xmlns:sec="http://www.thymeleaf.org/thymeleaf-extras-springsecurity5">
<head>
    <meta charset="UTF-8">
    <title>securitytest</title>
</head>
<think>嗯,用户想了解如何使用Spring Boot 3.2.5Spring Security 6.2.4实现微信登录。首先,我得理清楚微信登录的流程。微信OAuth2.0的流程一般是前端引导用户跳转到微信的授权页面,用户同意后,微信会返回一个code,后端用这个code去换access_tokenopenid,然后获取用户信息。 接下来,需要考虑Spring Security的OAuth2客户端配置。Spring Security 6.x之后,OAuth2的配置方式可能有变化,特别是从旧的spring-security-oauth2迁移到了新的支持方式。需要确认Spring Security 6.2.4是否支持OAuth2客户端的配置,以及如何配置。 首先,用户需要注册微信开放平台的应用,获取AppIDAppSecret,这是必须的。然后在Spring Boot项目中添加相关依赖,比如spring-boot-starter-oauth2-client,这个应该包含了Spring Security的OAuth2客户端支持。 然后,配置application.yml或者application.properties,设置微信的客户端配置,包括client-id、client-secret、授权范围、重定向URI等。微信的授权端点可能标准的OAuth2有所不同,需要找到正确的authorization-uritoken-uri,比如微信的授权URL是https://open.weixin.qq.com/connect/qrconnect,token URL是https://api.weixin.qq.com/sns/oauth2/access_token。 接下来,可能需要自定义一些组件,因为微信的响应格式可能不符合Spring Security的默认处理。例如,用户信息的端点返回的数据结构可能不同,需要自定义一个UserService来解析微信返回的用户信息,并转换为Spring Security的UserDetails对象。 另外,Spring Security默认的登录页面可能需要调整,或者需要配置自定义的登录页面,引导用户跳转到微信登录。或者使用前端的处理方式,比如在前端生成微信登录的链接,用户点击后跳转,后端处理回调。 还有,微信的OAuth2流程中,获取用户信息可能需要access_tokenopenid,所以在获取token之后,还需要调用微信的用户信息接口,比如https://api.weixin.qq.com/sns/userinfo。 在Spring Security中,可能需要实现一个OAuth2UserService接口,覆盖默认的加载用户流程,处理微信返回的数据。同时,用户信息可能需要保存到数据库中,或者直接使用微信的信息进行认证。 另外,跨域问题需要注意,特别是前端后端分离的情况下,需要配置CORS。同时,安全配置需要允许OAuth2的相关端点,比如/oauth2/authorization/weixin,以及回调的路径,比如/login/oauth2/code/weixin。 还需要考虑用户登录后的处理,比如生成JWT令牌,或者跳转到前端页面,保存用户会话等。如果使用JWT,可能需要配置Spring Security的过滤器链,添加JWT生成验证的过滤器。 测试过程中,可能需要使用内网穿透工具,因为微信的回调需要公网可访问的域名,开发时可以用ngrok或者localhost.run来暴露本地服务。 可能遇到的坑包括:微信的授权域名需要正确配置,回调地址必须在微信开放平台中设置;Spring Security的客户端注册ID需要配置中的一致;微信返回的字段名可能Spring Security默认的不同,需要自定义映射;还有可能因为版本问题,某些配置方式已经过时,需要查阅最新的文档。 最后,需要确保依赖的版本兼容性,Spring Boot 3.2.5对应的Spring Security版本是6.2.x,所以应该没问题。同时,要注意依赖管理,避免版本冲突。 总结下来,步骤大概是:注册微信应用,配置Spring Security的OAuth2客户端,自定义用户信息处理,处理回调,配置安全策略,测试整个流程。可能需要参考Spring Security微信的官方文档,确保各个参数正确无误。</think>以下是使用Spring Boot 3.2.5Spring Security 6.2.4实现微信登录的主要步骤: ### 一、前置准备 1. **注册微信开放平台** - 创建网站应用,获取`AppID``AppSecret` - 设置授权回调域(如`www.yourdomain.com`) 2. **添加依赖** ```xml <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-oauth2-client</artifactId> </dependency> ``` ### 二、配置Spring Security ```yaml # application.yml spring: security: oauth2: client: registration: weixin: client-id: your_appid client-secret: your_appsecret authorization-grant-type: authorization_code redirect-uri: "{baseUrl}/login/oauth2/code/weixin" scope: snsapi_login client-name: Weixin provider: weixin: authorization-uri: https://open.weixin.qq.com/connect/qrconnect token-uri: https://api.weixin.qq.com/sns/oauth2/access_token user-info-uri: https://api.weixin.qq.com/sns/userinfo user-name-attribute: openid ``` ### 三、自定义用户服务 ```java @Component public class WeixinOAuth2UserService implements OAuth2UserService<OAuth2UserRequest, OAuth2User> { @Override public OAuth2User loadUser(OAuth2UserRequest userRequest) throws OAuth2AuthenticationException { // 获取access_token OAuth2AccessToken accessToken = userRequest.getAccessToken(); // 调用微信API获取用户信息 String userInfoUrl = userRequest.getClientRegistration() .getProviderDetails().getUserInfoEndpoint().getUri(); userInfoUrl += "?access_token=" + accessToken.getTokenValue() + "&openid=" + ((DefaultOAuth2AccessToken)accessToken).getAdditionalParameters().get("openid"); // 解析微信返回的JSON数据 RestTemplate restTemplate = new RestTemplate(); Map<String, Object> userAttributes = restTemplate.getForObject(userInfoUrl, Map.class); return new DefaultOAuth2User( Collections.singleton(new SimpleGrantedAuthority("ROLE_USER")), userAttributes, "openid" // 对应微信返回的用户标识字段 ); } } ``` ### 四、安全配置 ```java @Configuration @EnableWebSecurity public class SecurityConfig { @Autowired private WeixinOAuth2UserService weixinOAuth2UserService; @Bean public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception { http .authorizeHttpRequests(auth -> auth .requestMatchers("/", "/login**").permitAll() .anyRequest().authenticated() ) .oauth2Login(oauth2 -> oauth2 .userInfoEndpoint(userInfo -> userInfo .userService(weixinOAuth2UserService) ) .defaultSuccessUrl("/userinfo", true) ) .csrf(csrf -> csrf.disable()); return http.build(); } } ``` ### 五、控制器示例 ```java @RestController public class UserController { @GetMapping("/userinfo") public Map<String, Object> userInfo(OAuth2User principal) { return principal.getAttributes(); // 返回微信用户信息 } } ``` ### 六、注意事项 1. **域名验证** - 必须使用备案域名 - 微信回调地址需与注册时一致 2. **Session管理** - 建议配置Redis实现分布式Session ```yaml spring: session: store-type: redis timeout: 3600 ``` 3. **安全增强** - 建议添加CSRF保护 - 启用HTTPS ### 七、测试流程 1. 访问 `http://localhost:8080/oauth2/authorization/weixin` 2. 跳转至微信登录页面 3. 用户授权后自动回调到 `/userinfo` 接口 ### 常见问题处理 1. **`redirect_uri`参数错误** - 检查微信开放平台配置的授权域名 - 确保回调地址完整匹配 2. **获取用户信息为空** - 确认`scope`设置为`snsapi_login` - 检查access_token是否有效 3. **跨域问题** ```java @Bean CorsConfigurationSource corsConfigurationSource() { CorsConfiguration config = new CorsConfiguration(); config.setAllowedOrigins(Arrays.asList("https://your-frontend-domain")); config.setAllowedMethods(Arrays.asList("*")); UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource(); source.registerCorsConfiguration("/**", config); return source; } ``` 以上方案基于Spring Security的OAuth2客户端实现,如需更复杂的业务逻辑(如自动注册本地用户),可在`WeixinOAuth2UserService`中添加数据库操作逻辑
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

罗马苏丹默罕默德

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值