Shiro登录成功后自定义操作


Shiro登录成功后,默认返回登录前访问的URL。但是有些时候,这样并不能满足程序的要求,例如要跳出IFrame,要实现这样的要求,可以覆盖FormAuthenticationFilter中的onLoginSuccess方法。

01 package com.ygsoft.security.shiro;
02   
03 import javax.servlet.ServletRequest;
04 import javax.servlet.ServletResponse;
05 import javax.servlet.http.HttpServletRequest;
06 import javax.servlet.http.HttpServletResponse;
07   
08 import org.apache.shiro.authc.AuthenticationToken;
09 import org.apache.shiro.subject.Subject;
10 import org.apache.shiro.web.filter.authc.FormAuthenticationFilter;
11 import org.apache.shiro.web.util.WebUtils;
12   
13 /**
14  *
15  * @author <a href="mailto:ketayao@gmail.com">ketayao</a>
16  * Version 1.1.0
17  * @since 2012-8-7 上午9:20:26
18  */
19   
20 public class CaptchaFormAuthenticationFilter extends FormAuthenticationFilter {
21   
22     private String captchaParam = SimpleCaptchaServlet.CAPTCHA_KEY;
23   
24     public String getCaptchaParam() {
25         return captchaParam;
26     }
27   
28     protected String getCaptcha(ServletRequest request) {
29         return WebUtils.getCleanParam(request, getCaptchaParam());
30     }
31   
32     @Override
33     protected AuthenticationToken createToken(ServletRequest request,
34             ServletResponse response) {
35         String username = getUsername(request);
36         String password = getPassword(request);
37         String captcha = getCaptcha(request);
38         boolean rememberMe = isRememberMe(request);
39         String host = getHost(request);
40         return new CaptchaUsernamePasswordToken(username, password, rememberMe,
41                 host, captcha);
42     }
43   
44     /**
45      * 覆盖默认实现,用sendRedirect直接跳出框架,以免造成js框架重复加载js出错。
46      * @param token
47      * @param subject
48      * @param request
49      * @param response
50      * @return
51      * @throws Exception 
52      * @see org.apache.shiro.web.filter.authc.FormAuthenticationFilter#onLoginSuccess(org.apache.shiro.authc.AuthenticationToken, org.apache.shiro.subject.Subject, javax.servlet.ServletRequest, javax.servlet.ServletResponse)
53      */
54     @Override
55     protected boolean onLoginSuccess(AuthenticationToken token, Subject subject,
56             ServletRequest request, ServletResponse response) throws Exception {
57         //issueSuccessRedirect(request, response);
58         //we handled the success redirect directly, prevent the chain from continuing:
59         HttpServletRequest httpServletRequest = (HttpServletRequest)request;
60         HttpServletResponse httpServletResponse = (HttpServletResponse)response;
61           
62         if (!"XMLHttpRequest".equalsIgnoreCase(httpServletRequest.getHeader("X-Requested-With"))
63                 || request.getParameter("ajax") == null) {// 不是ajax请求
64             httpServletResponse.sendRedirect(httpServletRequest.getContextPath() + this.getSuccessUrl());
65         else {
66             httpServletRequest.getRequestDispatcher("/login/timeout/success").forward(httpServletRequest, httpServletResponse);
67         }
68           
69         return false;
70     }
71 }
然后修改配置文件。

01 <!-- Shiro Filter -->
02     <bean id="shiroFilter" class="org.apache.shiro.spring.web.ShiroFilterFactoryBean">
03         <property name="securityManager" ref="securityManager" />
04         <property name="loginUrl" value="/login" />
05         <property name="successUrl" value="/management/index" />
06         <property name="filters">
07             <map>
08                  <entry key="authc" value-ref="captchaFormAuthenticationFilter"/>
09             </map>
10         </property>
11         <property name="filterChainDefinitions">
12             <value>
13                 /Captcha.jpg = anon
14                 /styles/** = anon
15                 /Captcha.jpg = anon
16                 /login/timeout = anon
17                 /login = authc
18                 /logout = logout
19                 /** = user
20             </value>
21         </property>
22     </bean>
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
好的,针对您的问题,您可以使用Shiro提供的权限注解 `@RequiresPermissions`,并通过自定义注解来实现权限控制。 以下是一个示例代码,其实现了一个自定义注解 `@ApiPermission`,并在 `ShiroFilterFactoryBean` 中添加了该注解,用于控制开放接口的访问权限: ```java @Retention(RetentionPolicy.RUNTIME) @Target(ElementType.METHOD) public @interface ApiPermission { String[] value() default {}; } public class ApiPermissionFilter extends AuthorizationFilter { @Override protected boolean isAccessAllowed(ServletRequest request, ServletResponse response, Object mappedValue) throws Exception { Subject subject = getSubject(request, response); String[] permissions = (String[]) mappedValue; if (permissions == null || permissions.length == 0) { return true; } for (String permission : permissions) { if (subject.isPermitted(permission)) { return true; } } return false; } } @Configuration public class ShiroConfig { @Bean public ShiroFilterFactoryBean shiroFilterFactoryBean(DefaultWebSecurityManager securityManager) { ShiroFilterFactoryBean factoryBean = new ShiroFilterFactoryBean(); factoryBean.setSecurityManager(securityManager); Map<String, Filter> filterMap = new LinkedHashMap<>(); filterMap.put("apiPermission", new ApiPermissionFilter()); factoryBean.setFilters(filterMap); Map<String, String> filterChainDefinitionMap = new LinkedHashMap<>(); filterChainDefinitionMap.put("/login", "anon"); filterChainDefinitionMap.put("/logout", "logout"); filterChainDefinitionMap.put("/api/**", "apiPermission[api:read]"); filterChainDefinitionMap.put("/**", "authc"); factoryBean.setFilterChainDefinitionMap(filterChainDefinitionMap); return factoryBean; } } @RestController public class ApiController { @GetMapping("/api/test") @ApiPermission("api:read") public String test() { return "Hello, World!"; } } ``` 在上述代码中,我们定义了一个 `ApiPermissionFilter`,用于判断用户是否具有访问开放接口的权限。然后,在 `ShiroFilterFactoryBean` 中添加了该过滤器,并在 `filterChainDefinitionMap` 中使用 `apiPermission[api:read]` 来控制 `/api/**` 下的所有请求的访问权限。 最后,在 `ApiController` 中使用 `@ApiPermission("api:read")` 注解来标识需要具有 `api:read` 权限才能访问的接口。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值