sso单点登录


前言

单点登录(SingleSignOn,SSO),就是通过用户的一次性鉴别登录。当用户在身份认证服务器上登录一次以后,即可获得访问单点登录系统中其他关联系统和应用软件的权限,同时这种实现是不需要管理员对用户的登录状态或其他信息进行修改的,这意味着在多个应用系统中,用户只需一次登录就可以访问所有相互信任的应用系统。这种方式减少了由登录产生的时间消耗,辅助了用户管理,是比较流行的


一、sso结构实现

二、使用步骤

2.1 建一个spring cloud 项目

 在总的父工程下添加 父工程使用

2.3.12.RELEASE 的springboot项目创建 然后添加以下
    <packaging>pom</packaging>
    <!--定义版本号-->
    <properties>
        <java.version>1.8</java.version>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <project.reporting.outputEncoding>UTF- 8</project.reporting.outputEncoding>
        <spring-cloud.version>Hoxton.SR8</spring-cloud.version>
        <spring-cloud-alibaba.version>2.2.3.RELEASE</spring-cloud-alibaba.version>
    </properties>
    <!--jar得管理 它只负责jar得管理不负责下载-->
    <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-dependencies</artifactId>
                <version>${spring-cloud.version}</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
            <dependency>
                <groupId>com.alibaba.cloud</groupId>
                <artifactId>spring-cloud-alibaba-dependencies</artifactId>
                <version>${spring-cloud-alibaba.version}</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
        </dependencies>
    </dependencyManagement>

其他二级模块和三级模块都是使用maven项目 每一个maven模块最后添加一个spring boot的启动类 

 2.2 common下的core的配置

引入依赖

<dependencies>
    <dependency>
        <groupId>org.projectlombok</groupId>
        <artifactId>lombok</artifactId>
    </dependency>
    <dependency>
        <groupId>com.auth0</groupId>
        <artifactId>java-jwt</artifactId>
        <version>3.18.3</version>
    </dependency>
    <dependency>
        <groupId>com.alibaba</groupId>
        <artifactId>fastjson</artifactId>
        <version>1.2.83</version>
    </dependency>
    <dependency>
        <groupId>com.baomidou</groupId>
        <artifactId>mybatis-plus-boot-starter</artifactId>
        <version>3.5.2</version>
    </dependency>
</dependencies>

添加实体类 工具类 

三个实体类 

@Data
@TableName(value = "cc_admin")
public class Admin implements Serializable {
    /**
     * 管理员表id
     */
    @TableId(value = "id",type = IdType.AUTO)
    private Integer id;

    /**
     * 管理员id
     */
    private String adminId;

    /**
     * 管理员用户名
     */
    private String adminUsername;

    /**
     * 管理员密码
     */
    private String adminPassword;

    /**
     * 管理员真实姓名
     */
    private String adminRealname;

    /**
     * 管理员密钥
     */
    private String salt;

    /**
     * 角色id
     */
    private String roleId;

    /**
     * 部门id
     */
    private String deptId;

    /**
     * 管理员性别
     */
    private String adminSex;

    /**
     * 管理员联系方式
     */
    private String adminTelephone;

    /**
     * 管理员年龄
     */
    private Integer adminAge;

    /**
     * 逻辑删除0(false)未删除,1(true)已删除
     */
    private Boolean isDeleted;

    /**
     * 创建时间
     */
    private Date gmtCreate;

    /**
     * 修改时间
     */
    private Date gmtModified;

    private static final long serialVersionUID = 1L;

    @Override
    public boolean equals(Object that) {
        if (this == that) {
            return true;
        }
        if (that == null) {
            return false;
        }
        if (getClass() != that.getClass()) {
            return false;
        }
        Admin other = (Admin) that;
        return (this.getId() == null ? other.getId() == null : this.getId().equals(other.getId()))
            && (this.getAdminId() == null ? other.getAdminId() == null : this.getAdminId().equals(other.getAdminId()))
            && (this.getAdminUsername() == null ? other.getAdminUsername() == null : this.getAdminUsername().equals(other.getAdminUsername()))
            && (this.getAdminPassword() == null ? other.getAdminPassword() == null : this.getAdminPassword().equals(other.getAdminPassword()))
            && (this.getAdminRealname() == null ? other.getAdminRealname() == null : this.getAdminRealname().equals(other.getAdminRealname()))
            && (this.getSalt() == null ? other.getSalt() == null : this.getSalt().equals(other.getSalt()))
            && (this.getRoleId() == null ? other.getRoleId() == null : this.getRoleId().equals(other.getRoleId()))
            && (this.getDeptId() == null ? other.getDeptId() == null : this.getDeptId().equals(other.getDeptId()))
            && (this.getAdminSex() == null ? other.getAdminSex() == null : this.getAdminSex().equals(other.getAdminSex()))
            && (this.getAdminTelephone() == null ? other.getAdminTelephone() == null : this.getAdminTelephone().equals(other.getAdminTelephone()))
            && (this.getAdminAge() == null ? other.getAdminAge() == null : this.getAdminAge().equals(other.getAdminAge()))
            && (this.getIsDeleted() == null ? other.getIsDeleted() == null : this.getIsDeleted().equals(other.getIsDeleted()))
            && (this.getGmtCreate() == null ? other.getGmtCreate() == null : this.getGmtCreate().equals(other.getGmtCreate()))
            && (this.getGmtModified() == null ? other.getGmtModified() == null : this.getGmtModified().equals(other.getGmtModified()));
    }

    @Override
    public int hashCode() {
        final int prime = 31;
        int result = 1;
        result = prime * result + ((getId() == null) ? 0 : getId().hashCode());
        result = prime * result + ((getAdminId() == null) ? 0 : getAdminId().hashCode());
        result = prime * result + ((getAdminUsername() == null) ? 0 : getAdminUsername().hashCode());
        result = prime * result + ((getAdminPassword() == null) ? 0 : getAdminPassword().hashCode());
        result = prime * result + ((getAdminRealname() == null) ? 0 : getAdminRealname().hashCode());
        result = prime * result + ((getSalt() == null) ? 0 : getSalt().hashCode());
        result = prime * result + ((getRoleId() == null) ? 0 : getRoleId().hashCode());
        result = prime * result + ((getDeptId() == null) ? 0 : getDeptId().hashCode());
        result = prime * result + ((getAdminSex() == null) ? 0 : getAdminSex().hashCode());
        result = prime * result + ((getAdminTelephone() == null) ? 0 : getAdminTelephone().hashCode());
        result = prime * result + ((getAdminAge() == null) ? 0 : getAdminAge().hashCode());
        result = prime * result + ((getIsDeleted() == null) ? 0 : getIsDeleted().hashCode());
        result = prime * result + ((getGmtCreate() == null) ? 0 : getGmtCreate().hashCode());
        result = prime * result + ((getGmtModified() == null) ? 0 : getGmtModified().hashCode());
        return result;
    }

    @Override
    public String toString() {
        StringBuilder sb = new StringBuilder();
        sb.append(getClass().getSimpleName());
        sb.append(" [");
        sb.append("Hash = ").append(hashCode());
        sb.append(", id=").append(id);
        sb.append(", adminId=").append(adminId);
        sb.append(", adminUsername=").append(adminUsername);
        sb.append(", adminPassword=").append(adminPassword);
        sb.append(", adminRealname=").append(adminRealname);
        sb.append(", salt=").append(salt);
        sb.append(", roleId=").append(roleId);
        sb.append(", deptId=").append(deptId);
        sb.append(", adminSex=").append(adminSex);
        sb.append(", adminTelephone=").append(adminTelephone);
        sb.append(", adminAge=").append(adminAge);
        sb.append(", isDeleted=").append(isDeleted);
        sb.append(", gmtCreate=").append(gmtCreate);
        sb.append(", gmtModified=").append(gmtModified);
        sb.append(", serialVersionUID=").append(serialVersionUID);
        sb.append("]");
        return sb.toString();
    }
}

/**
 * 权限
 * @TableName cc_permission
 */
@Data
@TableName(value = "cc_permission")
public class Permission implements Serializable {
    /**
     * 编号
     */
    @TableId(value = "id")
    private String id;

    /**
     * 所属上级
     */
    private String pid;

    /**
     * 名称
     */
    private String name;

    /**
     * 类型(1:菜单,2:按钮)
     */
    private Integer type;

    /**
     * 权限值
     */
    private String permissionValue;

    /**
     * 访问路径
     */
    private String path;

    /**
     * 组件路径
     */
    private String component;

    /**
     * 图标
     */
    private String icon;

    /**
     * 状态(0:正常,1:禁用)
     */
    private Integer status;

    /**
     * 逻辑删除 1(true)已删除, 0(false)未删除
     */
    private Integer isDeleted;

    /**
     * 创建时间
     */
    private Date gmtCreate;

    /**
     * 更新时间
     */
    private Date gmtModified;

    private static final long serialVersionUID = 1L;

    @Override
    public boolean equals(Object that) {
        if (this == that) {
            return true;
        }
        if (that == null) {
            return false;
        }
        if (getClass() != that.getClass()) {
            return false;
        }
        Permission other = (Permission) that;
        return (this.getId() == null ? other.getId() == null : this.getId().equals(other.getId()))
            && (this.getPid() == null ? other.getPid() == null : this.getPid().equals(other.getPid()))
            && (this.getName() == null ? other.getName() == null : this.getName().equals(other.getName()))
            && (this.getType() == null ? other.getType() == null : this.getType().equals(other.getType()))
            && (this.getPermissionValue() == null ? other.getPermissionValue() == null : this.getPermissionValue().equals(other.getPermissionValue()))
            && (this.getPath() == null ? other.getPath() == null : this.getPath().equals(other.getPath()))
            && (this.getComponent() == null ? other.getComponent() == null : this.getComponent().equals(other.getComponent()))
            && (this.getIcon() == null ? other.getIcon() == null : this.getIcon().equals(other.getIcon()))
            && (this.getStatus() == null ? other.getStatus() == null : this.getStatus().equals(other.getStatus()))
            && (this.getIsDeleted() == null ? other.getIsDeleted() == null : this.getIsDeleted().equals(other.getIsDeleted()))
            && (this.getGmtCreate() == null ? other.getGmtCreate() == null : this.getGmtCreate().equals(other.getGmtCreate()))
            && (this.getGmtModified() == null ? other.getGmtModified() == null : this.getGmtModified().equals(other.getGmtModified()));
    }

    @Override
    public int hashCode() {
        final int prime = 31;
        int result = 1;
        result = prime * result + ((getId() == null) ? 0 : getId().hashCode());
        result = prime * result + ((getPid() == null) ? 0 : getPid().hashCode());
        result = prime * result + ((getName() == null) ? 0 : getName().hashCode());
        result = prime * result + ((getType() == null) ? 0 : getType().hashCode());
        result = prime * result + ((getPermissionValue() == null) ? 0 : getPermissionValue().hashCode());
        result = prime * result + ((getPath() == null) ? 0 : getPath().hashCode());
        result = prime * result + ((getComponent() == null) ? 0 : getComponent().hashCode());
        result = prime * result + ((getIcon() == null) ? 0 : getIcon().hashCode());
        result = prime * result + ((getStatus() == null) ? 0 : getStatus().hashCode());
        result = prime * result + ((getIsDeleted() == null) ? 0 : getIsDeleted().hashCode());
        result = prime * result + ((getGmtCreate() == null) ? 0 : getGmtCreate().hashCode());
        result = prime * result + ((getGmtModified() == null) ? 0 : getGmtModified().hashCode());
        return result;
    }

    @Override
    public String toString() {
        StringBuilder sb = new StringBuilder();
        sb.append(getClass().getSimpleName());
        sb.append(" [");
        sb.append("Hash = ").append(hashCode());
        sb.append(", id=").append(id);
        sb.append(", pid=").append(pid);
        sb.append(", name=").append(name);
        sb.append(", type=").append(type);
        sb.append(", permissionValue=").append(permissionValue);
        sb.append(", path=").append(path);
        sb.append(", component=").append(component);
        sb.append(", icon=").append(icon);
        sb.append(", status=").append(status);
        sb.append(", isDeleted=").append(isDeleted);
        sb.append(", gmtCreate=").append(gmtCreate);
        sb.append(", gmtModified=").append(gmtModified);
        sb.append(", serialVersionUID=").append(serialVersionUID);
        sb.append("]");
        return sb.toString();
    }
}
@Data
@TableName(value = "cc_role")
public class Role implements Serializable {
    /**
     * 角色表id
     */
    @TableId(value = "id",type = IdType.AUTO)
    private Integer id;

    /**
     * 角色id
     */
    private String roleId;

    /**
     * 角色名称
     */
    private String roleName;

    /**
     * 角色描述
     */
    private String roleDescription;

    /**
     * 部门id
     */
    private String deptId;

    /**
     * 角色状态0(启用)1(禁用)
     */
    private Integer roleStatus;

    /**
     * 逻辑删除0(false)未删除,1(true)已删除
     */
    private Boolean isDeleted;

    /**
     * 创建时间
     */
    private Date gmtCreate;

    /**
     * 修改时间
     */
    private Date gmtModified;

    private static final long serialVersionUID = 1L;

    @Override
    public boolean equals(Object that) {
        if (this == that) {
            return true;
        }
        if (that == null) {
            return false;
        }
        if (getClass() != that.getClass()) {
            return false;
        }
        Role other = (Role) that;
        return (this.getId() == null ? other.getId() == null : this.getId().equals(other.getId()))
            && (this.getRoleId() == null ? other.getRoleId() == null : this.getRoleId().equals(other.getRoleId()))
            && (this.getRoleName() == null ? other.getRoleName() == null : this.getRoleName().equals(other.getRoleName()))
            && (this.getRoleDescription() == null ? other.getRoleDescription() == null : this.getRoleDescription().equals(other.getRoleDescription()))
            && (this.getDeptId() == null ? other.getDeptId() == null : this.getDeptId().equals(other.getDeptId()))
            && (this.getRoleStatus() == null ? other.getRoleStatus() == null : this.getRoleStatus().equals(other.getRoleStatus()))
            && (this.getIsDeleted() == null ? other.getIsDeleted() == null : this.getIsDeleted().equals(other.getIsDeleted()))
            && (this.getGmtCreate() == null ? other.getGmtCreate() == null : this.getGmtCreate().equals(other.getGmtCreate()))
            && (this.getGmtModified() == null ? other.getGmtModified() == null : this.getGmtModified().equals(other.getGmtModified()));
    }

    @Override
    public int hashCode() {
        final int prime = 31;
        int result = 1;
        result = prime * result + ((getId() == null) ? 0 : getId().hashCode());
        result = prime * result + ((getRoleId() == null) ? 0 : getRoleId().hashCode());
        result = prime * result + ((getRoleName() == null) ? 0 : getRoleName().hashCode());
        result = prime * result + ((getRoleDescription() == null) ? 0 : getRoleDescription().hashCode());
        result = prime * result + ((getDeptId() == null) ? 0 : getDeptId().hashCode());
        result = prime * result + ((getRoleStatus() == null) ? 0 : getRoleStatus().hashCode());
        result = prime * result + ((getIsDeleted() == null) ? 0 : getIsDeleted().hashCode());
        result = prime * result + ((getGmtCreate() == null) ? 0 : getGmtCreate().hashCode());
        result = prime * result + ((getGmtModified() == null) ? 0 : getGmtModified().hashCode());
        return result;
    }

    @Override
    public String toString() {
        StringBuilder sb = new StringBuilder();
        sb.append(getClass().getSimpleName());
        sb.append(" [");
        sb.append("Hash = ").append(hashCode());
        sb.append(", id=").append(id);
        sb.append(", roleId=").append(roleId);
        sb.append(", roleName=").append(roleName);
        sb.append(", roleDescription=").append(roleDescription);
        sb.append(", deptId=").append(deptId);
        sb.append(", roleStatus=").append(roleStatus);
        sb.append(", isDeleted=").append(isDeleted);
        sb.append(", gmtCreate=").append(gmtCreate);
        sb.append(", gmtModified=").append(gmtModified);
        sb.append(", serialVersionUID=").append(serialVersionUID);
        sb.append("]");
        return sb.toString();
    }
}

jwt工具类和前端数据处理vo

public class JwtUtil {
    private static String sign="xxx";
    //1.生成jwt的token方法
    public static String createJWT(Map<String,Object> map){
        //定义头信息
        Map<String,Object> head= new HashMap<>();
        head.put("alg","HS256");
        head.put("typ","JWT");
        //定义颁发时间
        Date iat=new Date();
        //过期时间
        Calendar expire = Calendar.getInstance();
        expire.set(Calendar.SECOND,24*3600);//24*3600
        Date expireTime = expire.getTime();

        String token = JWT.create()
                //头信息
                .withHeader(head)
                //设置颁发时间
                .withIssuedAt(iat)
                //设置过期时间
                .withExpiresAt(expireTime)
                //自定义的内容
                .withClaim("userinfo",map)
                //签名
                .sign(Algorithm.HMAC256(sign));
        return token;
    }

    //2.校验token是否有效
    public static boolean verifyToken(String token){
        //获取一个JWT校验对象
        JWTVerifier build = JWT.require(Algorithm.HMAC256(sign)).build();
        try {
            //调用校验功能
            DecodedJWT verify = build.verify(token);
            return true;
        }catch (Exception e){
            System.out.println("token无效");
            return false;
        }

    }

    //3.从token中获取相关的载荷内容
    public static Map<String,Object> getTokenChaim(String token){
        //获取一个JWT校验对象
        JWTVerifier build = JWT.require(Algorithm.HMAC256(sign)).build();
        //调用校验功能
        DecodedJWT verify = build.verify(token);
        Claim loginInfo = verify.getClaim("userinfo");
        return loginInfo.asMap();
    }
}

vo 返回给前端的统一数据处理类

@Data
@NoArgsConstructor
@AllArgsConstructor
public class Result<T> {
    private Integer code;
    private String msg;
    private T data;

    public Result(Integer code, String msg) {
        this.code = code;
        this.msg = msg;
    }
}

 2.3 实现系统的业务微服务

在modules添加需要的依赖

<dependencies>
        <dependency>
            <groupId>com.xin</groupId>
            <artifactId>xin-common-core</artifactId>
            <version>0.0.1-SNAPSHOT</version>
        </dependency>
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>5.1.49</version>
        </dependency>
<-- web启动类 -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
<-- nacos注册中心 -->
        <dependency>
            <groupId>com.alibaba.cloud</groupId>
            <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
        </dependency>
<-- 微服务之间的调用 -->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-openfeign</artifactId>
        </dependency>
    </dependencies>

在modules下新建system子模块 dao层和service使用mybatisX插件生成 启动类使用spring boot的

主要展示服务之间的控制层 

@RestController
@RequestMapping("system/permission")
public class PermissionController {
    @Autowired
    private PermissionService permissionService;

    @GetMapping("getPermissionByUserid/{userid}")
    public List<Permission> getPermissionByUserid(@PathVariable Integer userid){
         return permissionService.selectPermissionByUserid(userid);
    }
}
@RestController
@RequestMapping("system/admin")
public class AdminController {

    @Autowired
    private AdminService adminService;

    @GetMapping("/getByName/{name}")
    public Admin getByName(@PathVariable String name){
        QueryWrapper<Admin> wrapper=new QueryWrapper<>();
        wrapper.eq("admin_username",name);
        Admin admin = adminService.getOne(wrapper);
        return admin;
    }
}

配置文件

server.port=8087

spring.application.name=cai-system

spring.datasource.driver-class-name=com.mysql.jdbc.Driver
spring.datasource.url=jdbc:mysql://localhost:3306/caicai?serverTimezone=Asia/Shanghai
spring.datasource.password=root
spring.datasource.username=root

mybatis-plus.configuration.log-impl=org.apache.ibatis.logging.stdout.StdOutImpl

spring.cloud.nacos.discovery.server-addr=localhost:8848

2.4 sso模块的编写  

添加依赖

<dependencies>
    <!--引入common-core-->
    <dependency>
        <groupId>com.xin</groupId>
        <artifactId>xin-common-core</artifactId>
        <version>0.0.1-SNAPSHOT</version>
    </dependency>

<-- rdis启动 -->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-data-redis</artifactId>
    </dependency>

    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>
    <dependency>
        <groupId>com.alibaba.cloud</groupId>
        <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-security</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-openfeign</artifactId>
    </dependency>
    <dependency>
        <groupId>com.alibaba.cloud</groupId>
        <artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
    </dependency>
</dependencies>

 

@Configuration
public class MySecurityConfig extends WebSecurityConfigurerAdapter {

    @Autowired
    private UserService userService;

    @Autowired
    private StringRedisTemplate redisTemplate;
    @Bean
    public PasswordEncoder passwordEncoder() {
        //加盐加密: 原密码+盐===>哈希加密===>密文
        //   原密码===>哈希加密===>密文 [存储大量常见的密文]
        //123456+随机产生盐===>密文
        return new BCryptPasswordEncoder();
    }


    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        auth.userDetailsService(userService).passwordEncoder(passwordEncoder());
    }

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.formLogin()
                .successHandler(successHandler())
                .failureHandler(failureHandler())
                .loginProcessingUrl("/login").permitAll();

        http.cors();
        http.csrf().disable();
        http.authorizeRequests().anyRequest().authenticated();

    }

    private AuthenticationSuccessHandler successHandler() {
        return (request, response, authentication) -> {
            response.setContentType("application/json;charset=utf-8");
            PrintWriter writer = response.getWriter();
            //获取账号和权限
            String username = authentication.getPrincipal().toString();
            Collection<String> authorities = authentication.getAuthorities().stream().map(item->item.getAuthority()).collect(Collectors.toList());
            //根据账号和权限生产token;
            Map<String,Object> map=new HashMap<>();
            map.put("username",username);
            map.put("authorities",authorities);
            String token = JwtUtil.createJWT(map);

            //存入redis中。
            redisTemplate.opsForValue().set(token,"",30, TimeUnit.MINUTES);

            Result<String> result=new Result<>(2000,"登录成功",token);
            String jsonString = JSON.toJSONString(result);

            writer.print(jsonString);
            writer.flush();
            writer.close();
        };
    }

    private AuthenticationFailureHandler failureHandler() {
        return (request, response, e) -> {
            response.setContentType("application/json;charset=utf-8");
            PrintWriter writer = response.getWriter();

            Result<String> result=new Result<>(5000,"登录失败");
            String jsonString = JSON.toJSONString(result);

            writer.print(jsonString);
            writer.flush();
            writer.close();
        };
    }

    public static void main(String[] args) {
        BCryptPasswordEncoder passwordEncoder=new BCryptPasswordEncoder();
        System.out.println(passwordEncoder.encode("123456"));
    }
}

两个微服务的调用 


@FeignClient(value = "cai-system")
public interface AdminFeign {
    //建议:如果是服务之间的调用直接返回对象,如果是前端调用CommonResult
    @GetMapping("/system/admin/getByName/{name}")
    public Admin getByName(@PathVariable String name);
}

@FeignClient(value = "cai-system")
public interface PermissionFeign {

    @GetMapping("/system/permission/getPermissionByUserid/{userid}")
    public List<Permission> getPermissionByUserid(@PathVariable Integer userid);
}

自定义登录规则


@Service
public class UserService implements UserDetailsService {
    @Autowired
    private AdminFeign adminFeign;
    @Autowired
    private PermissionFeign permissionFeign;
    @Override
    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
        //1.根据用户名查询用户信息
        Admin admin = adminFeign.getByName(username);
        if(admin!=null){
            //2.根据当前用户查询该用户具有的权限。
            List<Permission> permissions = permissionFeign.getPermissionByUserid(admin.getId());
            Collection<SimpleGrantedAuthority> authorities = permissions.stream().filter(item->item.getPermissionValue()!=null).filter(item->item.getType()==2).map(item->new SimpleGrantedAuthority(item.getPermissionValue())).collect(Collectors.toList());
            User user = new User(admin.getAdminUsername(),admin.getAdminPassword(),authorities);
            return user;
        }
        return null;
    }
}

主启动类


/**
 * 排除多余的自动装配类可开启openfeign
 */
@SpringBootApplication(exclude = {DataSourceAutoConfiguration.class})
@EnableFeignClients
public class SsoApp {
    public static void main(String[] args) {
        SpringApplication.run(SsoApp.class,args);
    }
}

配置文件application.properties

server.port=8088

spring.application.name=cai-sso

spring.cloud.nacos.discovery.server-addr=localhost:8848

spring.redis.host=localhost
spring.redis.port=6379

#解决多个FeignClientSpecification' could not be registered
#开启重写多个feign接口
spring.main.allow-bean-definition-overriding=true

 这样SSo模块就完成了


总结

待补充

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值