springboot2+shiro访问无授权url时,会被shiro强制登出,但是我想要跳转到指定页面,并且不退出登录,这个怎么实现啊?
要实现在访问无授权的URL时跳转到指定页面并且不退出登录,您可以进行以下步骤:
在Shiro的配置文件中,找到对应的过滤器链配置(可能是shiroFilterFactoryBean或DefaultFilterChainManager),添加一个自定义的过滤器。
创建一个自定义过滤器类,继承Shiro原有的过滤器(如UserFilter),并重写onAccessDenied方法。在该方法中,实现跳转到指定页面的逻辑,而不是强制登出。
示例代码如下:
public class CustomUserFilter extends UserFilter {
@Override
protected boolean onAccessDenied(ServletRequest request, ServletResponse response) throws Exception {
Subject subject = getSubject(request, response);
if (subject.getPrincipal() == null) {
// 用户未登录的处理逻辑,可以根据需求进行跳转到登录页面或其他指定页面
WebUtils.issueRedirect(request, response, "/custom-page");
} else {
// 用户已登录但无权限访问的处理逻辑,可以根据需求进行跳转到指定页面
WebUtils.issueRedirect(request, response, "/unauthorized-page");
}
return false;
}
}
在Shiro的过滤器链配置中,将原有的user过滤器替换为自定义的过滤器。例如,在Spring Boot的配置类中,可以使用addFilterChainDefinition方法配置过滤器链,示例如下:
@Bean
public ShiroFilterFactoryBean shiroFilterFactoryBean() {
// ...其他配置...
// 获取过滤器链定义
Map<String, String> filterChainDefinitionMap = shiroFilterFactoryBean.getFilterChainDefinitionMap();
// 替换原有的user过滤器为自定义过滤器
filterChainDefinitionMap.put("user", "customUserFilter");
// ...其他配置...
return shiroFilterFactoryBean;
}
请注意,以上代码仅为示例,具体的配置可能因您的项目架构和需求而有所不同。建议理解Shiro的过滤器链配置和相关概念后,根据项目实际情况进行定制化开发。
【以下回答由 GPT 生成】
对于这个问题,可以通过定制shiro的配置来实现在访问无授权的URL时跳转到指定页面而不退出登录。
首先,在pom.xml文件中添加对shiro的依赖:
<dependency>
<groupId>org.apache.shiro</groupId>
<artifactId>shiro-spring-boot-web-starter</artifactId>
<version>1.7.1</version>
</dependency>
然后,在application.properties文件中配置shiro的相关属性:
# 配置shiro的登录URL
shiro.loginUrl=/login
# 配置shiro的未授权URL
shiro.unauthorizedUrl=/unauthorized
接下来,创建一个自定义的ShiroConfig类,并添加@Configuration注解:
@Configuration
public class ShiroConfig {
// 定义一个Bean,用于解析shiro的配置
@Bean
public ShiroFilterFactoryBean shiroFilterFactoryBean(SecurityManager securityManager) {
ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean();
shiroFilterFactoryBean.setSecurityManager(securityManager);
// 配置拦截器规则
Map<String, String> filterChainDefinitionMap = new LinkedHashMap<>();
// 添加需要授权的URL
filterChainDefinitionMap.put("/admin/**", "authc");
// 添加无授权跳转的URL
filterChainDefinitionMap.put("/**", "anon");
shiroFilterFactoryBean.setFilterChainDefinitionMap(filterChainDefinitionMap);
// 配置登录页面的URL
shiroFilterFactoryBean.setLoginUrl("/login");
// 配置未授权页面的URL
shiroFilterFactoryBean.setUnauthorizedUrl("/unauthorized");
return shiroFilterFactoryBean;
}
// 定义一个Bean,用于管理shiro的安全事务
@Bean
public SecurityManager securityManager() {
DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();
// 配置自定义的realm
securityManager.setRealm(customRealm());
return securityManager;
}
// 定义一个Bean,用于处理身份认证和授权
@Bean
public CustomRealm customRealm() {
return new CustomRealm();
}
}
再创建一个自定义的CustomRealm类,继承自AuthorizingRealm,并重写其方法:
public class CustomRealm extends AuthorizingRealm {
// 授权方法,用于判断用户是否有权限访问指定URL
@Override
protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
// 获取登录用户的信息
User user = (User) principalCollection.getPrimaryPrincipal();
SimpleAuthorizationInfo authorizationInfo = new SimpleAuthorizationInfo();
// 添加用户的权限信息
authorizationInfo.addStringPermission("admin");
return authorizationInfo;
}
// 认证方法,用于验证用户的身份信息
@Override
protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {
// 获取登录的用户名和密码
String username = (String) authenticationToken.getPrincipal();
String password = new String((char[]) authenticationToken.getCredentials());
// 此处应对用户名和密码进行验证,可以从数据库或其他存储中获取用户信息并进行验证
// 验证通过后返回认证信息
return new SimpleAuthenticationInfo(new User(username, password), password, getName());
}
}
最后,创建登录页面的Controller类和登录页面的html文件:
@Controller
public class LoginController {
@GetMapping("/login")
public String login() {
return "login";
}
}
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Login</title>
</head>
<body>
<h1>Login</h1>
<form method="post" action="/doLogin">
<input type="text" name="username" required />
<input type="password" name="password" required />
<input type="submit" value="Login" />
</form>
</body>
</html>
至此,已经实现了在访问无授权的URL时跳转到指定页面而不退出登录的功能。
【相关推荐】