springboot shiro 单点登录
时间: 2023-05-31 10:19:14 浏览: 193
### 回答1:
Spring Boot Shiro 单点登录是指使用Shiro框架实现的一种单点登录方式。它可以让用户在一次登录后,即可访问多个应用系统,而不需要再次登录。在实现单点登录时,需要使用Shiro的认证和授权功能,同时还需要使用一些其他的技术,如Cookie、Session等。通过使用Spring Boot和Shiro框架,可以快速实现单点登录功能,提高用户体验和系统安全性。
### 回答2:
单点登录(Single Sign-On,SSO)是指用户只需要在一次认证过程中,就可以访问多个应用程序的系统。这样可以极大地方便用户的使用,提高用户体验。Spring Boot和Shiro是目前非常流行的Web应用框架,在实现单点登录方面具有一定的优势。
在Spring Boot中,我们可以使用Spring Security来实现单点登录。Spring Security是Spring Framework的一个模块,提供了强大的身份验证和授权功能。它可以和Spring Boot无缝集成,简化了配置和部署流程。
在Shiro中,我们可以使用Shiro的Session共享功能来实现单点登录。Shiro是一个功能强大、灵活的Java安全框架,可以提供身份验证、授权、密码管理等安全功能。在Shiro中,我们可以将登录成功后生成的Session ID保存到共享存储中(例如Redis),然后在其他应用程序中获取该Session ID,并进行Session的验证。
无论是在Spring Boot中还是在Shiro中,实现单点登录需要以下几个步骤:
1. 在认证服务器上进行身份验证,并将生成的Session ID保存到共享存储中。
2. 在其他应用程序中获取Session ID,并进行Session的验证。
3. 如果Session验证成功,则自动登录到当前应用程序中。
需要注意的是,单点登录的实现需要考虑到安全性问题。一旦一个用户的Session ID被泄露,攻击者就可以直接访问用户的所有应用程序。因此,我们需要在共享存储中加密Session ID,并在传输过程中采用加密技术。同时,我们还需要定期更换Session ID,防止攻击者利用Session ID进行非法访问。
### 回答3:
Spring Boot是一个开源的Java Web框架,Shiro则是Apache的一款成熟的安全框架。在Spring Boot项目中使用Shiro可以帮助我们简化认证和授权方面的开发工作。而单点登录(Single Sign-On)可以在不同的应用中使用同一个认证信息以实现用户登录时只需要进行一次认证,就可以在多个应用中访问受保护的资源。
如何实现Spring Boot集成Shiro的单点登录呢?
1. 配置依赖
Shiro在Spring Boot的依赖包中已经被包含,只需要在pom.xml中添加Shiro Web的依赖即可:
<dependency>
<groupId>org.apache.shiro</groupId>
<artifactId>shiro-web</artifactId>
<version>1.4.1</version>
</dependency>
2. 配置shiro.ini文件
在项目中创建shiro.ini文件,文件包含一些shiro配置信息,例如对URL进行拦截的配置信息,用户的认证和授权信息等。在实现单点登录时,需要在shiro.ini中设置会话管理器和Cookie的相关信息。
[main]
# session管理器
customSessionManager = com.xxx.xxx.CustomSessionManager
sessionManager = org.apache.shiro.web.session.mgt.DefaultWebSessionManager
sessionManager.sessionDAO = org.apache.shiro.session.mgt.eis.EnterpriseCacheSessionDAO
# 会话Cookie ,其实官网已经介绍了
sessionIdCookie = org.apache.shiro.web.servlet.SimpleCookie
sessionIdCookie.name = MYSESSIONID
# 超时时间15分钟
sessionManager.globalSessionTimeout = 900000
# Cookie过期时间,浏览器关闭,则cookie过期,可以设置一个时间
sessionIdCookie.maxAge = -1
sessionIdCookie.path = /
sessionIdCookie.httpOnly = true
sessionIdCookie.secure = false
# 认证器
authc = org.apache.shiro.authc.pam.AllSuccessfulStrategy
# 配置自定义认证Realm
myRealm = com.xxx.xxx.MyRealm
securityManager.realms = $myRealm
securityManager.authenticator.authenticationStrategy = $authc
securityManager.sessionManager = $sessionManager
securityManager.sessionManager.sessionIdCookie = $sessionIdCookie
# 安全管理器
securityManager = org.apache.shiro.web.mgt.DefaultWebSecurityManager
# 相关配置
shiroFilter = org.apache.shiro.web.servlet.ShiroFilter
shiroFilter.securityManager = $securityManager
# 配置过滤器
filterChainDefinitions = /login.jsp = anon
/login = authc
/logout = logout
/**/*.html = authc
# 配置cacheManager 主要提升多次授权效率就是缓存
cacheManager = org.apache.shiro.cache.MemoryConstrainedCacheManager
securityManager.cacheManager = $cacheManager
3. 实现自定义Session管理器
创建CustomSessionManager类,实现Shiro的Session管理器接口,主要是为了在用户登录成功后将sessionId返回给客户端,同时也可以通过sessionId获取到用户的认证信息。
public class CustomSessionManager extends DefaultWebSessionManager {
@Override
protected Serializable getSessionId(ServletRequest request, ServletResponse response) {
Serializable sessionId = super.getSessionId(request, response);
HttpServletResponse httpResponse = WebUtils.toHttp(response);
httpResponse.setHeader("X-Token", sessionId.toString());
return sessionId;
}
}
4. 实现自定义Realm
创建MyRealm类,继承Shiro的AuthorizingRealm类,重写认证和授权方法。在这个类中,我们还需要处理单点登录的逻辑,如果用户已经登录了,那么如果之后再进行认证,应该直接返回已经认证的信息而不是再次进行认证。
public class MyRealm extends AuthorizingRealm {
@Override
protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
// 授权方法
// ...
}
@Override
protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
// 认证方法
// ...
}
@Override
protected void assertCredentialsMatch(AuthenticationToken token, AuthenticationInfo info) throws AuthenticationException {
// 处理单点登录逻辑
// ...
}
}
5. 配置Spring Boot的拦截器
在Spring Boot中,需要在WebSecurityConfigurerAdapter中配置Shiro的拦截器,同时需要实现一个CustomHttpSessionIdResolver类,将sessionId从请求头中获取。
@Configuration
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
http.addFilterBefore(shiroFilter(), BasicAuthenticationFilter.class)
.csrf().disable().cors();
}
@Bean
public ShiroFilterFactoryBean shiroFilter() {
// 配置过滤器,设置拦截器规则
SecurityManager securityManager = securityManager();
ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean();
shiroFilterFactoryBean.setSecurityManager(securityManager);
shiroFilterFactoryBean.setFilterChainDefinitions(filterChainDefinitions);
return shiroFilterFactoryBean;
}
@Bean
public SecurityManager securityManager() {
// 配置安全管理器,设置一些Shiro核心变量
DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();
securityManager.setRealm(myRealm());
securityManager.setSessionManager(sessionManager());
securityManager.setCacheManager(cacheManager());
return securityManager;
}
@Bean
public MyRealm myRealm() {
// 配置自定义Realm
MyRealm myRealm = new MyRealm();
return myRealm;
}
@Bean
public CacheManager cacheManager() {
// 配置缓存管理器
MemoryConstrainedCacheManager cacheManager = new MemoryConstrainedCacheManager();
return cacheManager;
}
@Bean
public CustomSessionManager sessionManager() {
// 配置Session管理器
CustomSessionManager sessionManager = new CustomSessionManager();
sessionManager.setSessionDAO(sessionDAO());
sessionManager.setGlobalSessionTimeout(1800000); // 30分钟超时
sessionManager.setSessionIdCookieEnabled(true);
sessionManager.setSessionIdCookie(sessionIdCookie());
return sessionManager;
}
@Bean
public SimpleCookie sessionIdCookie() {
// 配置sessionIdCookie
SimpleCookie simpleCookie = new SimpleCookie("MYSESSIONID");
simpleCookie.setHttpOnly(true);
simpleCookie.setPath("/");
simpleCookie.setMaxAge(-1); // 关闭浏览器则Cookie过期
return simpleCookie;
}
@Bean
public SessionDAO sessionDAO() {
// 配置SessionDAO
EnterpriseCacheSessionDAO sessionDAO = new EnterpriseCacheSessionDAO();
sessionDAO.setActiveSessionsCacheName("activeSessionsCache");
sessionDAO.setSessionIdGenerator(sessionIdGenerator());
return sessionDAO;
}
@Bean
public SessionIdGenerator sessionIdGenerator() {
// 配置SessionId生成规则
return new JavaUuidSessionIdGenerator();
}
@Bean
public CustomHttpSessionIdResolver customHttpSessionIdResolver(){
return new CustomHttpSessionIdResolver();
}
}
6. 自定义HttpSessionIdResolver类
这个类主要是为了从请求头中获取sessionId,而不是从Cookie中获取。
public class CustomHttpSessionIdResolver implements HttpSessionIdResolver {
@Override
public List<String> resolveSessionIds(HttpServletRequest request) {
return Collections.singletonList(request.getHeader("X-Token"));
}
@Override
public void setSessionId(HttpServletRequest request, HttpServletResponse response, String sessionId) {
response.setHeader("X-Token", sessionId);
}
@Override
public void expireSession(HttpServletRequest request, HttpServletResponse response) {
response.setHeader("X-Token", "");
}
}
以上便是Spring Boot集成Shiro实现单点登录的大致步骤。实现单点登录可以提高用户的使用体验,避免在一个系统中反复登录的问题,通过Shiro和Spring Boot的集成,我们可以更加便捷地实现单点登录。