JavaWeb中单点登录(SSO)的几种解决方案及原理

JavaWeb中单点登录(SSO)的几种解决方案及原理

一、Java 单点登录 (SSO) 有以下几种解决方案:

1、基于令牌(Token)的 SSO:用户在登录成功后,得到一个令牌,然后该令牌被用于访问其他相互信任的应用程序。Shiro 和 Spring Security 都支持基于令牌的 SSO。

2、基于代理(Proxy)的 SSO:一个代理服务器接收来自用户的请求,并将其重定向到适当的应用程序,并将用户身份验证信息传递给该应用程序。常见的代理服务器包括 Apache HTTP Server、Nginx 等。

3、基于中央认证授权(Central Authentication Authorization, CAS) 的 SSO:CAS 是一种开源的单点登录协议,它使用令牌来实现 SSO,可以与各种应用程序进行集成。CAS 服务器负责验证用户身份并生成令牌,应用程序则只需检查令牌即可。

4、基于安全标记(Security Assertion Markup Language, SAML) 的 SSO:SAML 是一种 XML 标记语言,用于在不同的应用程序之间交换用户身份验证和授权数据。当用户在一个应用程序上进行身份验证时,SAML 将会生成一个安全标记,并将其发送到其他应用程序以完成 SSO。

5、OAuth 和 OpenID Connect:OAuth 用于授权,OpenID Connect 则用于身份验证。它们都是基于令牌的 SSO 解决方案,被广泛应用于第三方身份验证和授权领域。

二、以下是使用 Java 编写基于 Spring Security 的简单 SSO 示例
1、基于 Cookie 的 SSO

 
// 配置认证中心
@Configuration
@EnableWebSecurity
public class AuthServerConfig extends WebSecurityConfigurerAdapter {
 
    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.authorizeRequests()
                .antMatchers("/login").permitAll()
                .anyRequest().authenticated()
                .and()
                .formLogin().loginPage("/login")
                .and()
                .logout().logoutSuccessUrl("/login").invalidateHttpSession(true)
                .deleteCookies("JSESSIONID", "MYAPPID");
    }
 
    @Bean
    @Override
    public AuthenticationManager authenticationManagerBean() throws Exception {
        return super.authenticationManagerBean();
    }
}
 
// 配置子应用
@Configuration
public class SubAppConfig {
    // ...
    @RequestMapping("/index")
    public String index() {
        return "index";
    }
 
    @RequestMapping("/sub/login")
    public String subLogin(HttpServletRequest request, HttpServletResponse response) {
        // 检查是否已经登录,如果已经登录就不需要再次重定向到认证中心了
        if (request.getCookies() != null) {
            for (Cookie cookie : request.getCookies()) {
                if ("MYAPPID".equals(cookie.getName())) {
                    return "index";
                }
            }
        }
 
        // 未登录则跳转到认证中心进行认证
        response.sendRedirect("http://authserver.com/login?redirect_uri=http://subapp.com/sub/login/callback");
        return null;
    }
 
    @RequestMapping("/sub/login/callback")
    public String subLoginCallback(HttpServletRequest request, HttpServletResponse response) {
        // 认证中心认证成功后会重定向到此接口,携带认证令牌
        String token = request.getParameter("token");
 
        // 将认证令牌保存为 Cookie,并跳转回子应用首页
        Cookie cookie = new Cookie("MYAPPID", token);
        cookie.setPath("/");
        cookie.setMaxAge(24 * 60 * 60);
        response.addCookie(cookie);
        return "index";
    }
}

2、基于JWT的SSO

// 配置认证中心
@Configuration
@EnableWebSecurity
public class AuthServerConfig extends WebSecurityConfigurerAdapter {
 
    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.authorizeRequests()
                .antMatchers("/login").permitAll()
                .anyRequest().authenticated()
                .and()
                .formLogin().loginPage("/login")
                .and()
                .logout().logoutSuccessUrl("/login").invalidateHttpSession(true)
                .deleteCookies("JSESSIONID");
    }
 
    @Bean
    @Override
    public AuthenticationManager authenticationManagerBean() throws Exception {
        return super.authenticationManagerBean();
    }
}
 
// 配置子应用
@Configuration
public class SubAppConfig {
 
    @Autowired
    private RestTemplate restTemplate;
 
    @Value("${authserver.url:http://authserver.com}")
    private String authServerUrl;
 
    @Value("${jwt.secret}")
    private String jwtSecret;
 
    @RequestMapping("/index")
    public String index(HttpServletRequest request) {
        String token = getTokenFromCookie(request);
        String username = getUsernameFromToken(token);
 
        // ...
    }
 
    @RequestMapping("/sub/login")
    public String subLogin(HttpServletRequest request, HttpServletResponse response) {
        // 检查是否已经登录,如果已经登录就不需要再次重定向到认证中心了
        String token = getTokenFromCookie(request);
        if (StringUtils.isNotEmpty(token)) {
            return "index";
        }
 
        // 未登录则跳转到认证中心进行认证
        response.sendRedirect(authServerUrl + "/login?redirect_uri=http://subapp.com/sub/login/callback");
        return null;
    }
 
    @RequestMapping("/sub/login/callback")
    public String subLoginCallback(HttpServletRequest request, HttpServletResponse response) {
        // 认证中心认证成功后会重定向到此接口,携带 JWT
        String jwt = request.getParameter("jwt");
 
        // 验证 JWT 签名,并解析出用户信息
        Claims claims = Jwts.parser().setSigningKey(jwtSecret).parseClaimsJws(jwt).
JavaWeb,单选框可以使用JSTL标签库来实现。可以使用<c:forEach>标签来遍历选项,并使用<c:if>标签来判断是否选。例如,在HTML表单,可以使用<input type="radio">标签来创建单选框,使用checked属性来指定初始选的标记。以下是一个示例代码: ```html <form action="/xxx/xxx.jsp" method="post"> <br/> 性别: <input id="man" type="radio" value="1" name="gender">男   <input id="woman" checked="checked" value="2" type="radio" name="gender">女<br/> </form> ``` 在上述示例,单选框的初始选标记使用checked="checked"属性来指定。具体来说,第一个单选框指定了id为"man",值为1,名称为"gender";第二个单选框指定了id为"woman",值为2,名称为"gender",并且使用checked="checked"属性来设置初始选标记。在提交表单时,选择的值将会被发送到服务器端进行处理。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* *2* [JavaWeb数据回显 下拉列表、单选框、多选框 选状态](https://blog.csdn.net/m0_48660016/article/details/121308723)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] - *3* [JavaWeb_HTML(13)_HTML 表单_单选框](https://blog.csdn.net/qq_36260974/article/details/88370727)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] [ .reference_list ]
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值