上一篇文章《实战Spring Cloud Oauth2系列(二)实战编写一个oauth认证服务器》我们编写了一个oauth2的服务端,同时可以跑起来了,大家可以测试下,这篇文章我们介绍下自定义查询用户的数据结构。
在使用spring security编写oauth2的时候,我们可以看到没有编写任何一个接口,此时在这里查询user表的数据的时候,就完全是oauth这套框架来完成的。但是在实际的场景里面,我们会涉及到一些实际定义的用户数据结构,那么此时我们怎么来操作呢?
其实在上一篇文章的时候,我们介绍了,在oauthconfig的这个类里面有一个方法:
public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception {
endpoints.userDetailsService(userService)
.authenticationManager(authenticationManager)
.tokenStore(this.getJdbcTokenStore());
}在这里我们就可以自定义个这个查询的类,然后我们使用endpoints.userDetailsService这个方法来配置我们自己的user查询类。在前面的源码里面已经呈现了,这里我们来看看这个类的具体实现:
package org.shop.oauth.server.service;
import org.springframework.security.core.userdetails.UserDetailsService;
public interface UserService extends UserDetailsService{
}首先如果我们需要自定义一个user查询方法的话,那么我们需要创建一个类,这个类必须要继承自UserDetailsService这个类。当集成这个类之后,这里就只有一个方法:
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException{}我们实现这个方法的逻辑就是根据用户名来查询对应的用户,具体的实现如下:
package org.shop.oauth.server.service.impl;
import org.shop.common.http.exception.ShopException;
import org.shop.common.model.http.ResultCode;
import org.shop.common.mysql.auth.mapper.UserEntityDao;
import org.shop.common.mysql.auth.model.UserEntity;
import org.shop.common.mysql.auth.model.UserPrincipal;
import org.shop.oauth.server.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.authentication.InternalAuthenticationServiceException;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.stereotype.Service;
import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import lombok.extern.slf4j.Slf4j;
@Service
@Slf4j
public class UserServiceImpl implements UserService {
@Autowired
private UserEntityDao userDao;
@Override
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
QueryWrapper<UserEntity> queryWrapper = new QueryWrapper<UserEntity>();
queryWrapper.eq("username", username);
UserEntity userEntity = userDao.selectOne(queryWrapper);
if (userEntity != null) {
if (userEntity.getStatus() == 2) {
throw new ShopException(ResultCode.ACCOUNTDISABLED.getMessage());
} else if (userEntity.getStatus() == 3) {
throw new ShopException(ResultCode.ACCOUNTLOCKED.getMessage());
} else if (userEntity.getStatus() == 4) {
throw new ShopException(ResultCode.ACCOUNTEXPIRED.getMessage());
}
log.info("通过用户名: {} 获取user信息:{}",username,JSON.toJSONString(userEntity));
return new UserPrincipal(userEntity);
} else {
log.info("通过用户名: {} 没有找到对应的用户",username);
throw new ShopException(ResultCode.USERNAMEORPASSWORDERROR.getMessage());
}
}
}这里我们可以做一些粗略的判断,例如:用户查询不到,用户的状态不对等等。可以在这里做一些错误的异常处理。方便用户在认证的时候查询对应的错误信息。
以上就是自定义查询用户的代码逻辑介绍。
备注:
1、这里只有这个方法,通过用户名查询用户,如果是密码模式的时候,用户还需要传递密码,此时密码如果输入错误,那么在这里是无法进行判断的。
最后按照惯例,附上本案例的源码,登录后即可下载









还没有评论,来说两句吧...