Anyone?

> _____________________________________________ 
> From:         [email protected]
> [mailto:[email protected]]  On Behalf Of Keith Garry Boyce
> Sent: Friday, January 16, 2009 9:53 AM
> To:   [email protected]
> Subject:      CAS without CAS login page using restful api and
> modifiedlogin-webflow.xml
> 
> I wanted to code a JSF application where the login page is a JSF page
> rather than a CAS page. I see this as a use case that cannot be overlooked
> in present day application development.
> 
> I understand that it is discouraged to present credentials to an
> application but an applications security model shouldn't have to be custom
> for every security solution plugged in.
> 
> In my case I'm using spring security as the mechanism to glue the security
> stuff together. If I switch from plain security to CAS security it seems
> that all documentation points to me doing custom things for the login page
> such as iframe etc..
> 
> So here's what I've come up with. I'd appreciate feedback on this
> solution:
> 
> In login-webflow.xml I made it so if ticketGrantingTicketId is passed as a
> parameter on the /cas/login URL then
> Service cookie can be issued directly using the ticketGrantingTicketId. In
> my case I get the ticketGrantingTicketId using the CAS restful api.
> 
>       <action-state id="initialFlowSetup">
>               <action bean="initialFlowSetupAction" />
> <!-- garpinc replace -->
> <!--
>               <transition on="success"
> to="ticketGrantingTicketExistsCheck" />
> -->
> <!-- garpinc with -->
>               <transition on="success"
> to="ticketGrantingTicketIdExistsCheck" />
> <!-- garpinc end replace -->
>       </action-state>
> 
>       <!-- added by garpinc -->
>       <decision-state id="ticketGrantingTicketIdExistsCheck">
>               <if test="${requestParameters.ticketGrantingTicketId ==
> null}" then="ticketGrantingTicketExistsCheck"
> else="populateFromRequestParams" />
>       </decision-state>
> 
>       <action-state id="populateFromRequestParams">
>               <set attribute="ticketGrantingTicketId" 
>                    value="requestParameters.ticketGrantingTicketId"
>                    scope="flow"/>
>               <transition on="success" to="sendTicketGrantingTicket" />
>       </action-state>
>       <!-- end of garpinc add -->
> 
> 
> Then I define a JSF controller. The pseudo steps are as follows
> 1) username/password provided to jsf page
> 2) adaptAuthenticationRequest is called to change this into an
> Authentication CasAuthenticationProvider can process
> 3) user is authenticated using provider
> 4) to participate in SSO getFinalOutcome is called which redirects to
> /cas/login with ticketGrantingTicketId and service which is page you want
> to go to on successful login.
> 
> public class CasAuthenticationController extends
>               AbstractAuthenticationController {
>       
>       private static final String CAS_TGR = "CAS_TGR";
>       private ServiceProperties serviceProperties;
> 
>       public void setServiceProperties(ServiceProperties
> serviceProperties) {
>               this.serviceProperties = serviceProperties;
>       }
>       
>       private String secureCasURL;
> 
>       public void setSecureCasURL(String secureCasURL) {
>               this.secureCasURL = secureCasURL;
>       }
> 
>       private String ticketURL;
> 
>       public void setTicketURL(String ticketURL) {
>               this.ticketURL = ticketURL;
>       }
>       
>       private boolean useCasSSO = true;
> 
>       public void setUseCasSSO(boolean useCasSSO) {
>               this.useCasSSO = useCasSSO;
>       }
> 
> 
>       protected void updateFacesContext(Authentication aut) {
> 
>       }
> 
> 
>       final protected String getFinalOutcome(String outcome) {
>               
>               if (outcome.equals("success") && useCasSSO) {
>                       FacesContext ctx =
> FacesContext.getCurrentInstance();
>                       ExternalContext extCtx = ctx.getExternalContext();
> 
>                       HttpServletRequest request =    
>                       (HttpServletRequest) extCtx.getRequest();
>                       String ticket = (String)
> request.getAttribute(CAS_TGR);
> 
>                       try {
>                               extCtx.redirect(
>                                                 secureCasURL
>                                               + "/login?service="
>                                               + request.getScheme() +
> "://" + request.getServerName() + ":" + request.getServerPort() +
> request.getContextPath()
>                                               +
> "/view/secure/facelet/content/home.iface&ticketGrantingTicketId=" +
> ticket);
>                               // this is ignored because extCtx.redirect
>                               return "redirect";
>                       } catch (IOException e) {
>                               throw new RuntimeException(e);
>                       }
>                       
>               } else {
>                       return outcome;
>               }
>       }
>       
>       protected Authentication adaptAuthenticationRequest(
>                       UsernamePasswordAuthenticationToken
> usernamePasswordAuthenticationToken) throws Exception {
> 
>         HttpClient client = new HttpClient();
> 
>         PostMethod post = new PostMethod(ticketURL);
>         NameValuePair[] usernamePasswordArray = {
>                       new
> NameValuePair("username",usernamePasswordAuthenticationToken.getPrincipal(
> ).toString()),
>                       new
> NameValuePair("password",usernamePasswordAuthenticationToken.getCredential
> s().toString())
>         };
>         post.setRequestBody(usernamePasswordArray);
>         int responseCode = client.executeMethod(post);
>         if (responseCode != 201) {
>               String body = post.getResponseBodyAsString();
>               Pattern pattern = Pattern.compile(".*<h3>(.*)</h3>.*",
> Pattern.DOTALL);
>               Matcher matcher = pattern.matcher(body);
>               if (matcher.matches()) {
>                       String casError = matcher.group(1);
>               throw new AuthenticationServiceException(casError);
>               } else {
>                       throw new RuntimeException("body does not contain an
> error:" + body);
>               }
> 
>         }
>         String ticketGrantingResource =
> post.getResponseHeader("Location").getValue();
>         
>         Pattern pattern = Pattern.compile(".*\\/(.*)");
>         Matcher matcher = pattern.matcher(ticketGrantingResource);
>         if (matcher.matches()) {
>               String ticketGrantingResourceToStore = matcher.group(1);
>               // Update cookie in browser for SSO
>               HttpServletRequest request =    
>                       (HttpServletRequest)
> FacesContext.getCurrentInstance()
>  
> .getExternalContext().getRequest();
>               request.setAttribute(CAS_TGR,
> ticketGrantingResourceToStore);
> 
>         } else {
>               throw new RuntimeException("ticketGrantingResource not in
> right format:" + ticketGrantingResource);
>         }
>         
>         post = new PostMethod(ticketGrantingResource);
>         NameValuePair[] serviceArray = {
>                       new
> NameValuePair("service",serviceProperties.getService()),
>         };
>         
>         post.setRequestBody(serviceArray);
>         responseCode = client.executeMethod(post);
>         if (responseCode != 200) {
>               throw new RuntimeException("response code was: " +
> responseCode);
>         }
>         String ticket = post.getResponseBodyAsString();
>         
>         return new UsernamePasswordAuthenticationToken(
>                       CasProcessingFilter.CAS_STATEFUL_IDENTIFIER,
>                       ticket);
> 
>       }
> 
> 
>       
> } << File: ATT00037.txt >> 

<<attachment: winmail.dat>>

_______________________________________________
Yale CAS mailing list
[email protected]
http://tp.its.yale.edu/mailman/listinfo/cas

Reply via email to