Classes in this File | Line Coverage | Branch Coverage | Complexity | ||||
CasFilter |
|
| 1.8333333333333333;1.833 |
1 | /* | |
2 | * Licensed to the Apache Software Foundation (ASF) under one | |
3 | * or more contributor license agreements. See the NOTICE file | |
4 | * distributed with this work for additional information | |
5 | * regarding copyright ownership. The ASF licenses this file | |
6 | * to you under the Apache License, Version 2.0 (the | |
7 | * "License"); you may not use this file except in compliance | |
8 | * with the License. You may obtain a copy of the License at | |
9 | * | |
10 | * http://www.apache.org/licenses/LICENSE-2.0 | |
11 | * | |
12 | * Unless required by applicable law or agreed to in writing, | |
13 | * software distributed under the License is distributed on an | |
14 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY | |
15 | * KIND, either express or implied. See the License for the | |
16 | * specific language governing permissions and limitations | |
17 | * under the License. | |
18 | */ | |
19 | package org.apache.shiro.cas; | |
20 | ||
21 | import org.apache.shiro.authc.AuthenticationException; | |
22 | import org.apache.shiro.authc.AuthenticationToken; | |
23 | import org.apache.shiro.subject.Subject; | |
24 | import org.apache.shiro.web.filter.authc.AuthenticatingFilter; | |
25 | import org.apache.shiro.web.util.WebUtils; | |
26 | import org.slf4j.Logger; | |
27 | import org.slf4j.LoggerFactory; | |
28 | ||
29 | import javax.servlet.ServletRequest; | |
30 | import javax.servlet.ServletResponse; | |
31 | import javax.servlet.http.HttpServletRequest; | |
32 | import java.io.IOException; | |
33 | ||
34 | /** | |
35 | * This filter validates the CAS service ticket to authenticate the user. It must be configured on the URL recognized | |
36 | * by the CAS server. For example, in {@code shiro.ini}: | |
37 | * <pre> | |
38 | * [main] | |
39 | * casFilter = org.apache.shiro.cas.CasFilter | |
40 | * ... | |
41 | * | |
42 | * [urls] | |
43 | * /shiro-cas = casFilter | |
44 | * ... | |
45 | * </pre> | |
46 | * (example : http://host:port/mycontextpath/shiro-cas) | |
47 | * | |
48 | * @since 1.2 | |
49 | */ | |
50 | 0 | public class CasFilter extends AuthenticatingFilter { |
51 | ||
52 | 0 | private static Logger logger = LoggerFactory.getLogger(CasFilter.class); |
53 | ||
54 | // the name of the parameter service ticket in url | |
55 | private static final String TICKET_PARAMETER = "ticket"; | |
56 | ||
57 | // the url where the application is redirected if the CAS service ticket validation failed (example : /mycontextpatch/cas_error.jsp) | |
58 | private String failureUrl; | |
59 | ||
60 | /** | |
61 | * The token created for this authentication is a CasToken containing the CAS service ticket received on the CAS service url (on which | |
62 | * the filter must be configured). | |
63 | * | |
64 | * @param request the incoming request | |
65 | * @param response the outgoing response | |
66 | * @throws Exception if there is an error processing the request. | |
67 | */ | |
68 | @Override | |
69 | protected AuthenticationToken createToken(ServletRequest request, ServletResponse response) throws Exception { | |
70 | 0 | HttpServletRequest httpRequest = (HttpServletRequest) request; |
71 | 0 | String ticket = httpRequest.getParameter(TICKET_PARAMETER); |
72 | 0 | return new CasToken(ticket); |
73 | } | |
74 | ||
75 | /** | |
76 | * Execute login by creating {@link #createToken(javax.servlet.ServletRequest, javax.servlet.ServletResponse) token} and logging subject | |
77 | * with this token. | |
78 | * | |
79 | * @param request the incoming request | |
80 | * @param response the outgoing response | |
81 | * @throws Exception if there is an error processing the request. | |
82 | */ | |
83 | @Override | |
84 | protected boolean onAccessDenied(ServletRequest request, ServletResponse response) throws Exception { | |
85 | 0 | return executeLogin(request, response); |
86 | } | |
87 | ||
88 | /** | |
89 | * Returns <code>false</code> to always force authentication (user is never considered authenticated by this filter). | |
90 | * | |
91 | * @param request the incoming request | |
92 | * @param response the outgoing response | |
93 | * @param mappedValue the filter-specific config value mapped to this filter in the URL rules mappings. | |
94 | * @return <code>false</code> | |
95 | */ | |
96 | @Override | |
97 | protected boolean isAccessAllowed(ServletRequest request, ServletResponse response, Object mappedValue) { | |
98 | 0 | return false; |
99 | } | |
100 | ||
101 | /** | |
102 | * If login has been successful, redirect user to the original protected url. | |
103 | * | |
104 | * @param token the token representing the current authentication | |
105 | * @param subject the current authenticated subjet | |
106 | * @param request the incoming request | |
107 | * @param response the outgoing response | |
108 | * @throws Exception if there is an error processing the request. | |
109 | */ | |
110 | @Override | |
111 | protected boolean onLoginSuccess(AuthenticationToken token, Subject subject, ServletRequest request, | |
112 | ServletResponse response) throws Exception { | |
113 | 0 | issueSuccessRedirect(request, response); |
114 | 0 | return false; |
115 | } | |
116 | ||
117 | /** | |
118 | * If login has failed, redirect user to the CAS error page (no ticket or ticket validation failed) except if the user is already | |
119 | * authenticated, in which case redirect to the default success url. | |
120 | * | |
121 | * @param token the token representing the current authentication | |
122 | * @param ae the current authentication exception | |
123 | * @param request the incoming request | |
124 | * @param response the outgoing response | |
125 | */ | |
126 | @Override | |
127 | protected boolean onLoginFailure(AuthenticationToken token, AuthenticationException ae, ServletRequest request, | |
128 | ServletResponse response) { | |
129 | 0 | if (logger.isDebugEnabled()) { |
130 | 0 | logger.debug( "Authentication exception", ae ); |
131 | } | |
132 | // is user authenticated or in remember me mode ? | |
133 | 0 | Subject subject = getSubject(request, response); |
134 | 0 | if (subject.isAuthenticated() || subject.isRemembered()) { |
135 | try { | |
136 | 0 | issueSuccessRedirect(request, response); |
137 | 0 | } catch (Exception e) { |
138 | 0 | logger.error("Cannot redirect to the default success url", e); |
139 | 0 | } |
140 | } else { | |
141 | try { | |
142 | 0 | WebUtils.issueRedirect(request, response, failureUrl); |
143 | 0 | } catch (IOException e) { |
144 | 0 | logger.error("Cannot redirect to failure url : {}", failureUrl, e); |
145 | 0 | } |
146 | } | |
147 | 0 | return false; |
148 | } | |
149 | ||
150 | public void setFailureUrl(String failureUrl) { | |
151 | 0 | this.failureUrl = failureUrl; |
152 | 0 | } |
153 | } |