Skip to content

Commit

Permalink
#2 Add ALA-Auth cookie support
Browse files Browse the repository at this point in the history
  • Loading branch information
sbearcsiro committed Aug 1, 2017
1 parent 7b0bac9 commit 93e50fc
Show file tree
Hide file tree
Showing 7 changed files with 154 additions and 18 deletions.
Original file line number Diff line number Diff line change
@@ -1,24 +1,64 @@
package au.org.ala.cas.webflow

import org.apereo.cas.ticket.registry.TicketRegistrySupport
import org.apereo.cas.web.support.CookieRetrievingCookieGenerator
import org.springframework.beans.factory.annotation.Autowired
import org.springframework.beans.factory.annotation.Qualifier
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean
import org.springframework.boot.context.properties.EnableConfigurationProperties
import org.springframework.cloud.context.config.annotation.RefreshScope
import org.springframework.context.annotation.Bean
import org.springframework.context.annotation.Configuration
import org.springframework.webflow.definition.registry.FlowDefinitionRegistry
import org.springframework.webflow.engine.builder.support.FlowBuilderServices

@Configuration("alaCasWebflowConfiguration")
@EnableConfigurationProperties(AuthCookieProperties::class)
open class AlaCasWebflowConfiguration {

@Autowired
lateinit var authCookieProperties: AuthCookieProperties

@Autowired
@Qualifier("loginFlowRegistry")
lateinit var loginFlowDefinitionRegistry: FlowDefinitionRegistry

@Autowired
@Qualifier("logoutFlowRegistry")
lateinit var logoutFlowDefinitionRegistry: FlowDefinitionRegistry

@Autowired
lateinit var flowBuilderServices: FlowBuilderServices

@ConditionalOnMissingBean(name = arrayOf("authCookeWebflowConfigurer"))
@Bean("authCookeWebflowConfigurer")
open fun authCookeWebflowConfigurer(): AuthCookieWebflowConfigurer = AuthCookieWebflowConfigurer(flowBuilderServices, loginFlowDefinitionRegistry)
@Autowired
@Qualifier("defaultTicketRegistrySupport")
lateinit var ticketRegistrySupport: TicketRegistrySupport

@Bean
@RefreshScope
@Qualifier("alaProxyAuthenticationCookieGenerator")
open fun alaProxyAuthenticationCookieGenerator(): CookieRetrievingCookieGenerator =
authCookieProperties.cookie.run { CookieRetrievingCookieGenerator(name, path, maxAge, isSecure, domain, isHttpOnly) }

@Bean
@RefreshScope
open fun generateAuthCookieAction(
@Qualifier("alaProxyAuthenticationCookieGenerator") alaProxyAuthenticationCookieGenerator: CookieRetrievingCookieGenerator
): GenerateAuthCookieAction =
GenerateAuthCookieAction(ticketRegistrySupport, alaProxyAuthenticationCookieGenerator)

@Bean
@RefreshScope
open fun removeAuthCookieAction(
@Qualifier("alaProxyAuthenticationCookieGenerator") alaProxyAuthenticationCookieGenerator: CookieRetrievingCookieGenerator
): RemoveAuthCookieAction =
RemoveAuthCookieAction(alaProxyAuthenticationCookieGenerator)

@ConditionalOnMissingBean(name = arrayOf("authCookieWebflowConfigurer"))
@Bean("authCookieWebflowConfigurer")
open fun authCookieWebflowConfigurer(
generateAuthCookieAction: GenerateAuthCookieAction,
removeAuthCookieAction: RemoveAuthCookieAction
): AuthCookieWebflowConfigurer =
AuthCookieWebflowConfigurer(flowBuilderServices, loginFlowDefinitionRegistry, logoutFlowDefinitionRegistry, generateAuthCookieAction, removeAuthCookieAction)
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
package au.org.ala.cas.webflow

import org.apereo.cas.configuration.model.support.cookie.CookieProperties
import org.springframework.boot.context.properties.ConfigurationProperties

@ConfigurationProperties(value = "auth")
open class AuthCookieProperties(
var cookie: CookieProperties = CookieProperties()
)
Original file line number Diff line number Diff line change
Expand Up @@ -5,34 +5,49 @@ import org.apereo.cas.authentication.principal.Response
import org.apereo.cas.web.flow.CasWebflowConstants
import org.apereo.cas.web.flow.DefaultWebflowConfigurer
import org.springframework.webflow.definition.registry.FlowDefinitionRegistry
import org.springframework.webflow.engine.ActionState
import org.springframework.webflow.engine.Flow
import org.springframework.webflow.engine.builder.support.FlowBuilderServices

class AuthCookieWebflowConfigurer(
flowBuilderServices: FlowBuilderServices,
loginFlowDefinitionRegistry: FlowDefinitionRegistry) :
loginFlowDefinitionRegistry: FlowDefinitionRegistry,
logoutFlowDefinitionRegistry: FlowDefinitionRegistry,
val generateAuthCookieAction: GenerateAuthCookieAction,
val removeAuthCookieAction: RemoveAuthCookieAction) :
DefaultWebflowConfigurer(flowBuilderServices, loginFlowDefinitionRegistry) {

init {
this.logoutFlowDefinitionRegistry = logoutFlowDefinitionRegistry
}

companion object {
val log = logger<AuthCookieWebflowConfigurer>()
}

override fun doInitialize() {
log.info("doInitialize()")
// createRedirectToServiceActionState(loginFlow)

val inFlow = loginFlow
val outFlow = logoutFlow

if (inFlow != null) {
doGenerateAuthCookieOnLoginAction(inFlow)
}

if (outFlow != null) {
doRemoveAuthCookieOnLogoutAction(outFlow)
}
}

private fun doGenerateAuthCookieOnLoginAction(flow: Flow) {
val sendTicketGrantingTicketAction = flow.getState(CasWebflowConstants.STATE_ID_SEND_TICKET_GRANTING_TICKET) as ActionState
sendTicketGrantingTicketAction.exitActionList.add(generateAuthCookieAction)
}

/**
* Create redirect to service action state.
* @param flow the flow
*/
override protected fun createRedirectToServiceActionState(flow: Flow) {
val redirectToView = createActionState(flow,
CasWebflowConstants.STATE_ID_REDIRECT,
createEvaluateAction("redirectToServiceAction"))
createTransitionForState(redirectToView, Response.ResponseType.POST.name.toLowerCase(), CasWebflowConstants.STATE_ID_POST_VIEW)
createTransitionForState(redirectToView, Response.ResponseType.REDIRECT.name.toLowerCase(), CasWebflowConstants.STATE_ID_REDIR_VIEW)
private fun doRemoveAuthCookieOnLogoutAction(flow: Flow) {
val doLogoutAction = flow.getState(CasWebflowConstants.STATE_ID_DO_LOGOUT) as ActionState
doLogoutAction.entryActionList.add(removeAuthCookieAction)
}

}
37 changes: 37 additions & 0 deletions src/main/kotlin/au/org/ala/cas/webflow/GenerateAuthCookieAction.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
package au.org.ala.cas.webflow

import au.org.ala.utils.logger
import org.apereo.cas.authentication.AuthenticationException
import org.apereo.cas.ticket.InvalidTicketException
import org.apereo.cas.ticket.registry.TicketRegistrySupport
import org.apereo.cas.web.support.CookieRetrievingCookieGenerator
import org.apereo.cas.web.support.WebUtils
import org.springframework.webflow.action.AbstractAction
import org.springframework.webflow.execution.Event
import org.springframework.webflow.execution.RequestContext

open class GenerateAuthCookieAction(val ticketRegistrySupport: TicketRegistrySupport,
val alaProxyAuthenticationCookieGenerator: CookieRetrievingCookieGenerator) : AbstractAction() {

companion object {
val log = logger<GenerateAuthCookieAction>()
}

override fun doExecute(context: RequestContext): Event {

log.error("GenerateAuthCookieAction running")
//
// Create ALA specific cookie that any ALA web application can read
//
val ticketGrantingTicket = WebUtils.getTicketGrantingTicketId(context)
log.debug("Ticket-granting ticket found in the context is [{}]", ticketGrantingTicket)

val authentication = this.ticketRegistrySupport.getAuthenticationFrom(ticketGrantingTicket) ?: throw InvalidTicketException(AuthenticationException("No authentication found for ticket " + ticketGrantingTicket), ticketGrantingTicket)
val email = authentication.principal.id

alaProxyAuthenticationCookieGenerator.addCookie(WebUtils.getHttpServletRequest(context), WebUtils.getHttpServletResponse(context), email)

return success()
}

}
25 changes: 25 additions & 0 deletions src/main/kotlin/au/org/ala/cas/webflow/RemoveAuthCookieAction.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
package au.org.ala.cas.webflow

import au.org.ala.utils.logger
import org.apereo.cas.web.support.CookieRetrievingCookieGenerator
import org.apereo.cas.web.support.WebUtils
import org.springframework.webflow.action.AbstractAction
import org.springframework.webflow.execution.Event
import org.springframework.webflow.execution.RequestContext

open class RemoveAuthCookieAction(
val alaProxyAuthenticationCookieGenerator: CookieRetrievingCookieGenerator
) : AbstractAction() {

companion object {
val log = logger<RemoveAuthCookieAction>()
}

override fun doExecute(context: RequestContext?): Event {
log.error("GenerateAuthCookieAction running")
val response = WebUtils.getHttpServletResponse(context)
alaProxyAuthenticationCookieGenerator.removeCookie(response)
return success() // unnecessary?
}

}
2 changes: 1 addition & 1 deletion src/main/resources/META-INF/spring.factories
Original file line number Diff line number Diff line change
@@ -1 +1 @@
org.springframework.boot.autoconfigure.EnableAutoConfiguration=au.org.ala.cas.ServletContextConfig
org.springframework.boot.autoconfigure.EnableAutoConfiguration=au.org.ala.cas.ServletContextConfig,au.org.ala.cas.webflow.AlaCasWebflowConfiguration
12 changes: 11 additions & 1 deletion src/main/resources/application.yml
Original file line number Diff line number Diff line change
Expand Up @@ -132,4 +132,14 @@ cas:

jdbc:
showSql: true
genDdl: true
genDdl: true

# Override these for non-ALA deployments
auth:
cookie:
domain: ala.org.au
httpOnly: true
maxAge: -1
name: ALA-Auth
path: /
secure: false

0 comments on commit 93e50fc

Please sign in to comment.