下面列出了org.springframework.web.servlet.view.JstlView#org.jasig.cas.CasProtocolConstants 实例代码,或者点击链接到github查看源代码,也可以在右侧发表评论。
@Override
protected void prepareMergedOutputModel(final Map<String, Object> model, final HttpServletRequest request,
final HttpServletResponse response) throws Exception {
super.prepareMergedOutputModel(model, request, response);
final Service service = super.getServiceFrom(model);
final RegisteredService registeredService = this.servicesManager.findServiceBy(service);
final Map<String, Object> attributes = new HashMap<>(getPrincipalAttributesAsMultiValuedAttributes(model));
attributes.put(CasProtocolConstants.VALIDATION_CAS_MODEL_ATTRIBUTE_NAME_AUTHENTICATION_DATE,
Collections.singleton(getAuthenticationDate(model)));
attributes.put(CasProtocolConstants.VALIDATION_CAS_MODEL_ATTRIBUTE_NAME_FROM_NEW_LOGIN,
Collections.singleton(isAssertionBackedByNewLogin(model)));
attributes.put(CasProtocolConstants.VALIDATION_REMEMBER_ME_ATTRIBUTE_NAME,
Collections.singleton(isRememberMeAuthentication(model)));
decideIfCredentialPasswordShouldBeReleasedAsAttribute(attributes, model, registeredService);
decideIfProxyGrantingTicketShouldBeReleasedAsAttribute(attributes, model, registeredService);
super.putIntoModel(model,
CasProtocolConstants.VALIDATION_CAS_MODEL_ATTRIBUTE_NAME_ATTRIBUTES,
this.casAttributeEncoder.encodeAttributes(attributes, getServiceFrom(model)));
}
/**
* Tries to determine if authentication was created as part of a "renew" event.
* Renewed authentications can occur if the service is not allowed to participate
* in SSO or if a "renew" request parameter is specified.
*
* @param ctx the request context
* @return true if renewed
*/
private boolean isAuthenticationRenewed(final RequestContext ctx) {
if (ctx.getRequestParameters().contains(CasProtocolConstants.PARAMETER_RENEW)) {
LOGGER.debug("[{}] is specified for the request. The authentication session will be considered renewed.",
CasProtocolConstants.PARAMETER_RENEW);
return true;
}
final Service service = WebUtils.getService(ctx);
if (service != null) {
final RegisteredService registeredService = this.servicesManager.findServiceBy(service);
if (registeredService != null) {
final boolean isAllowedForSso = registeredService.getAccessStrategy().isServiceAccessAllowedForSso();
LOGGER.debug("Located [{}] in registry. Service access to participate in SSO is set to [{}]",
registeredService.getServiceId(), isAllowedForSso);
return !isAllowedForSso;
}
}
return false;
}
private Map<?, ?> renderView() throws Exception{
final ModelAndView modelAndView = this.getModelAndViewUponServiceValidationWithSecurePgtUrl();
final JstlView v = (JstlView) resolver.resolveViewName(modelAndView.getViewName(), Locale.getDefault());
final MockHttpServletRequest req = new MockHttpServletRequest(new MockServletContext());
v.setServletContext(req.getServletContext());
req.setAttribute(RequestContext.WEB_APPLICATION_CONTEXT_ATTRIBUTE,
new GenericWebApplicationContext(req.getServletContext()));
final Cas30ResponseView view = new Cas30ResponseView(v);
view.setServicesManager(this.servicesManager);
view.setCasAttributeEncoder(new DefaultCasAttributeEncoder(this.servicesManager));
final MockHttpServletResponse resp = new MockHttpServletResponse();
view.render(modelAndView.getModel(), req, resp);
return (Map<?, ?>) req.getAttribute(CasProtocolConstants.VALIDATION_CAS_MODEL_ATTRIBUTE_NAME_ATTRIBUTES);
}
@Test
public void verifyView() throws Exception {
final ModelAndView modelAndView = this.getModelAndViewUponServiceValidationWithSecurePgtUrl();
final JstlView v = (JstlView) resolver.resolveViewName(modelAndView.getViewName(), Locale.getDefault());
final MockHttpServletRequest req = new MockHttpServletRequest(new MockServletContext());
v.setServletContext(req.getServletContext());
req.setAttribute(RequestContext.WEB_APPLICATION_CONTEXT_ATTRIBUTE,
new GenericWebApplicationContext(req.getServletContext()));
final Cas20ResponseView view = new Cas20ResponseView(v);
final MockHttpServletResponse resp = new MockHttpServletResponse();
view.render(modelAndView.getModel(), req, resp);
assertNotNull(req.getAttribute(CasViewConstants.MODEL_ATTRIBUTE_NAME_CHAINED_AUTHENTICATIONS));
assertNotNull(req.getAttribute(CasViewConstants.MODEL_ATTRIBUTE_NAME_PRIMARY_AUTHENTICATION));
assertNotNull(req.getAttribute(CasViewConstants.MODEL_ATTRIBUTE_NAME_PRINCIPAL));
assertNotNull(req.getAttribute(CasProtocolConstants.VALIDATION_CAS_MODEL_PROXY_GRANTING_TICKET_IOU));
}
@Test
public void verifySsoSessionCookieOnRenewAsParameter() throws Exception {
final MockHttpServletResponse response = new MockHttpServletResponse();
final MockHttpServletRequest request = new MockHttpServletRequest();
request.addParameter(CasProtocolConstants.PARAMETER_RENEW, "true");
final TicketGrantingTicket tgt = mock(TicketGrantingTicket.class);
when(tgt.getId()).thenReturn("test");
request.setCookies(new Cookie("TGT", "test5"));
WebUtils.putTicketGrantingTicketInScopes(this.context, tgt);
this.context.setExternalContext(new ServletExternalContext(new MockServletContext(), request, response));
this.action.setCreateSsoSessionCookieOnRenewAuthentications(false);
assertEquals("success", this.action.execute(this.context).getId());
assertEquals(0, response.getCookies().length);
}
/**
* Is request asking for service ticket?
*
* @param context the context
* @return true, if both service and tgt are found, and the request is not asking to renew.
* @since 4.1.0
*/
protected boolean isRequestAskingForServiceTicket(final RequestContext context) {
final String ticketGrantingTicketId = WebUtils.getTicketGrantingTicketId(context);
final Service service = WebUtils.getService(context);
return (StringUtils.isNotBlank(context.getRequestParameters().get(CasProtocolConstants.PARAMETER_RENEW))
&& ticketGrantingTicketId != null
&& service != null);
}
@Test
public void verifyResponseWithoutAuthMethod() throws Exception {
final Map<String, Object> model = new HashMap<>();
final Map<String, Object> attributes = new HashMap<>();
attributes.put("testAttribute", "testValue");
final Principal principal = new DefaultPrincipalFactory().createPrincipal("testPrincipal", attributes);
final Map<String, Object> authnAttributes = new HashMap<>();
authnAttributes.put("authnAttribute1", "authnAttrbuteV1");
authnAttributes.put("authnAttribute2", "authnAttrbuteV2");
authnAttributes.put(RememberMeCredential.AUTHENTICATION_ATTRIBUTE_REMEMBER_ME, Boolean.TRUE);
final Authentication primary = TestUtils.getAuthentication(principal, authnAttributes);
final Assertion assertion = new ImmutableAssertion(
primary, Collections.singletonList(primary), TestUtils.getService(), true);
model.put("assertion", assertion);
final MockHttpServletResponse servletResponse = new MockHttpServletResponse();
this.response.renderMergedOutputModel(model, new MockHttpServletRequest(), servletResponse);
final String written = servletResponse.getContentAsString();
assertTrue(written.contains("testPrincipal"));
assertTrue(written.contains("testAttribute"));
assertTrue(written.contains("testValue"));
assertTrue(written.contains("authnAttribute1"));
assertTrue(written.contains("authnAttribute2"));
assertTrue(written.contains(CasProtocolConstants.VALIDATION_REMEMBER_ME_ATTRIBUTE_NAME));
assertTrue(written.contains("urn:oasis:names:tc:SAML:1.0:am:unspecified"));
}
/**
* Is request asking for service ticket?
*
* @param context the context
* @return true, if both service and tgt are found, and the request is not asking to renew.
* @since 4.1.0
*/
protected boolean isRequestAskingForServiceTicket(final RequestContext context) {
final String ticketGrantingTicketId = WebUtils.getTicketGrantingTicketId(context);
final Service service = WebUtils.getService(context);
return (StringUtils.isNotBlank(context.getRequestParameters().get(CasProtocolConstants.PARAMETER_RENEW))
&& ticketGrantingTicketId != null
&& service != null);
}
/**
* Overrideable method to determine which credentials to use to grant a
* proxy granting ticket. Default is to use the pgtUrl.
*
* @param service the webapp service requesting proxy
* @param request the HttpServletRequest object.
* @return the credentials or null if there was an error or no credentials
* provided.
*/
protected Credential getServiceCredentialsFromRequest(final WebApplicationService service, final HttpServletRequest request) {
final String pgtUrl = request.getParameter(CasProtocolConstants.PARAMETER_PROXY_CALLBACK_URL);
if (StringUtils.hasText(pgtUrl)) {
try {
final RegisteredService registeredService = this.servicesManager.findServiceBy(service);
verifyRegisteredServiceProperties(registeredService, service);
return new HttpBasedServiceCredential(new URL(pgtUrl), registeredService);
} catch (final Exception e) {
logger.error("Error constructing pgtUrl", e);
}
}
return null;
}
@Test
public void verifyViewAuthnAttributes() throws Exception {
final Map<?, ?> attributes = renderView();
assertTrue(attributes.containsKey(CasProtocolConstants.VALIDATION_CAS_MODEL_ATTRIBUTE_NAME_AUTHENTICATION_DATE));
assertTrue(attributes.containsKey(CasProtocolConstants.VALIDATION_CAS_MODEL_ATTRIBUTE_NAME_FROM_NEW_LOGIN));
assertTrue(attributes.containsKey(CasProtocolConstants.VALIDATION_REMEMBER_ME_ATTRIBUTE_NAME));
}
@Override
protected void prepareMergedOutputModel(final Map<String, Object> model, final HttpServletRequest request,
final HttpServletResponse response) throws Exception {
super.prepareMergedOutputModel(model, request, response);
final Service service = super.getServiceFrom(model);
final RegisteredService registeredService = this.servicesManager.findServiceBy(service);
final Map<String, Object> attributes = new HashMap<>(getPrincipalAttributesAsMultiValuedAttributes(model));
attributes.put(CasProtocolConstants.VALIDATION_CAS_MODEL_ATTRIBUTE_NAME_AUTHENTICATION_DATE,
Collections.singleton(getAuthenticationDate(model)));
attributes.put(CasProtocolConstants.VALIDATION_CAS_MODEL_ATTRIBUTE_NAME_FROM_NEW_LOGIN,
Collections.singleton(isAssertionBackedByNewLogin(model)));
attributes.put(CasProtocolConstants.VALIDATION_REMEMBER_ME_ATTRIBUTE_NAME,
Collections.singleton(isRememberMeAuthentication(model)));
decideIfCredentialPasswordShouldBeReleasedAsAttribute(attributes, model, registeredService);
decideIfProxyGrantingTicketShouldBeReleasedAsAttribute(attributes, model, registeredService);
attributes.put(this.authenticationMethodResponseAttribute,
getAuthenticationAttribute(model, MultiFactorAuthenticationSupportingWebApplicationService.CONST_PARAM_AUTHN_METHOD));
super.putIntoModel(model,
CasProtocolConstants.VALIDATION_CAS_MODEL_ATTRIBUTE_NAME_ATTRIBUTES,
this.casAttributeEncoder.encodeAttributes(attributes, getServiceFrom(model)));
}
@Override
protected Event doExecute(final RequestContext context) throws Exception {
final MultiFactorAuthenticationTransactionContext mfaTx = MultiFactorRequestContextUtils.getMfaTransaction(context);
if (mfaTx == null) {
return new Event(this, EVENT_ID_REQUIRE_TGT);
}
final MultiFactorAuthenticationSupportingWebApplicationService mfaService =
this.authnMethodRankingStrategy.computeHighestRankingAuthenticationMethod(mfaTx);
final String requestedAuthenticationMethod = mfaService != null ? mfaService.getAuthenticationMethod() : null;
final String tgt = MultiFactorRequestContextUtils.getTicketGrantingTicketId(context);
/*
* If the TGT is blank i.e. there is no existing SSO session, proceed with normal login flow
* (Note that flow may need interrupted later if the CAS-using service requires an authentication method
* not fulfilled by the normal login flow)
*/
if (StringUtils.isBlank(tgt)) {
logger.trace("TGT is blank; proceed flow normally.");
return new Event(this, EVENT_ID_REQUIRE_TGT);
}
/*
* If the authentication method the CAS-using service has specified is blank,
* proceed with the normal login flow.
*/
if (StringUtils.isBlank(requestedAuthenticationMethod)) {
logger.trace("Since required authentication method is blank, proceed flow normally.");
return new Event(this, EVENT_ID_REQUIRE_TGT);
}
logger.trace("Service [{}] requires authentication method [{}]", mfaTx.getTargetServiceId(), requestedAuthenticationMethod);
final Authentication authentication = this.authenticationSupport.getAuthenticationFrom(tgt);
/*
* If somehow the TGT were to have no authentication, then interpret as an existing SSO session insufficient
* to fulfill the requirements of this service, and branch to fulfill the authentication requirement.
*/
if (authentication == null) {
logger.warn("TGT had no Authentication, which is odd. "
+ "Proceeding as if additional authentication required.");
//Place the ranked mfa service into the flow scope to be available in the actual mfa subflows
MultiFactorRequestContextUtils.setMultifactorWebApplicationService(context, mfaService);
return new Event(this, getMultiFactorEventIdByAuthenticationMethod(requestedAuthenticationMethod));
}
final Set<String> previouslyAchievedAuthenticationMethods =
MultiFactorUtils.getSatisfiedAuthenticationMethods(authentication);
/*
* If any of the recorded authentication methods from the prior Authentication are 'stronger'
* than the authentication method requested to access the CAS-using service, proceed with the normal authentication flow.
*/
if (this.authnMethodRankingStrategy
.anyPreviouslyAchievedAuthenticationMethodsStrongerThanRequestedOne(previouslyAchievedAuthenticationMethods,
requestedAuthenticationMethod)) {
logger.trace("Authentication method [{}] is EQUAL -- OR -- WEAKER than any previously fulfilled methods [{}]; "
+ "proceeding with flow normally...", requestedAuthenticationMethod, previouslyAchievedAuthenticationMethods);
return new Event(this, EVENT_ID_REQUIRE_TGT);
}
if (context.getRequestParameters().get(CasProtocolConstants.PARAMETER_RENEW) != null) {
return new Event(this, EVENT_ID_REQUIRE_TGT);
}
logger.trace("Authentication method [{}] is STRONGER than any previously fulfilled methods [{}]; "
+ "branching to prompt for required authentication method.",
requestedAuthenticationMethod, previouslyAchievedAuthenticationMethods);
//Place the ranked mfa service into the flow scope to be available in the actual mfa subflows
MultiFactorRequestContextUtils.setMultifactorWebApplicationService(context, mfaService);
return new Event(this, getMultiFactorEventIdByAuthenticationMethod(requestedAuthenticationMethod));
}