View Javadoc
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   * @see <a href="https://github.com/bujiio/buji-pac4j">buji-pac4j</a>
50   * @deprecated replaced with Shiro integration in <a href="https://github.com/bujiio/buji-pac4j">buji-pac4j</a>.
51   */
52  @Deprecated
53  public class CasFilter extends AuthenticatingFilter {
54      
55      private static Logger logger = LoggerFactory.getLogger(CasFilter.class);
56      
57      // the name of the parameter service ticket in url
58      private static final String TICKET_PARAMETER = "ticket";
59      
60      // the url where the application is redirected if the CAS service ticket validation failed (example : /mycontextpatch/cas_error.jsp)
61      private String failureUrl;
62      
63      /**
64       * The token created for this authentication is a CasToken containing the CAS service ticket received on the CAS service url (on which
65       * the filter must be configured).
66       * 
67       * @param request the incoming request
68       * @param response the outgoing response
69       * @throws Exception if there is an error processing the request.
70       */
71      @Override
72      protected AuthenticationToken createToken(ServletRequest request, ServletResponse response) throws Exception {
73          HttpServletRequest httpRequest = (HttpServletRequest) request;
74          String ticket = httpRequest.getParameter(TICKET_PARAMETER);
75          return new CasToken(ticket);
76      }
77      
78      /**
79       * Execute login by creating {@link #createToken(javax.servlet.ServletRequest, javax.servlet.ServletResponse) token} and logging subject
80       * with this token.
81       * 
82       * @param request the incoming request
83       * @param response the outgoing response
84       * @throws Exception if there is an error processing the request.
85       */
86      @Override
87      protected boolean onAccessDenied(ServletRequest request, ServletResponse response) throws Exception {
88          return executeLogin(request, response);
89      }
90      
91      /**
92       * Returns <code>false</code> to always force authentication (user is never considered authenticated by this filter).
93       * 
94       * @param request the incoming request
95       * @param response the outgoing response
96       * @param mappedValue the filter-specific config value mapped to this filter in the URL rules mappings.
97       * @return <code>false</code>
98       */
99      @Override
100     protected boolean isAccessAllowed(ServletRequest request, ServletResponse response, Object mappedValue) {
101         return false;
102     }
103     
104     /**
105      * If login has been successful, redirect user to the original protected url.
106      * 
107      * @param token the token representing the current authentication
108      * @param subject the current authenticated subjet
109      * @param request the incoming request
110      * @param response the outgoing response
111      * @throws Exception if there is an error processing the request.
112      */
113     @Override
114     protected boolean onLoginSuccess(AuthenticationToken token, Subject subject, ServletRequest request,
115                                      ServletResponse response) throws Exception {
116         issueSuccessRedirect(request, response);
117         return false;
118     }
119     
120     /**
121      * If login has failed, redirect user to the CAS error page (no ticket or ticket validation failed) except if the user is already
122      * authenticated, in which case redirect to the default success url.
123      * 
124      * @param token the token representing the current authentication
125      * @param ae the current authentication exception
126      * @param request the incoming request
127      * @param response the outgoing response
128      */
129     @Override
130     protected boolean onLoginFailure(AuthenticationToken token, AuthenticationException ae, ServletRequest request,
131                                      ServletResponse response) {
132         if (logger.isDebugEnabled()) {
133             logger.debug( "Authentication exception", ae );
134         }
135         // is user authenticated or in remember me mode ?
136         Subject subject = getSubject(request, response);
137         if (subject.isAuthenticated() || subject.isRemembered()) {
138             try {
139                 issueSuccessRedirect(request, response);
140             } catch (Exception e) {
141                 logger.error("Cannot redirect to the default success url", e);
142             }
143         } else {
144             try {
145                 WebUtils.issueRedirect(request, response, failureUrl);
146             } catch (IOException e) {
147                 logger.error("Cannot redirect to failure url : {}", failureUrl, e);
148             }
149         }
150         return false;
151     }
152     
153     public void setFailureUrl(String failureUrl) {
154         this.failureUrl = failureUrl;
155     }
156 }