<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
	xmlns:mvc="http://www.springframework.org/schema/mvc" 
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xmlns:tx="http://www.springframework.org/schema/tx" 
	xmlns:context="http://www.springframework.org/schema/context"
	xmlns:security="http://www.springframework.org/schema/security"
	xmlns:task="http://www.springframework.org/schema/task" 
	xmlns:oauth="http://www.springframework.org/schema/security/oauth2"
	xsi:schemaLocation="http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-3.0.xsd
		http://www.springframework.org/schema/security/oauth2 http://www.springframework.org/schema/security/spring-security-oauth2-1.0.xsd
		http://www.springframework.org/schema/task http://www.springframework.org/schema/task/spring-task-3.1.xsd
		http://www.springframework.org/schema/security http://www.springframework.org/schema/security/spring-security-3.1.xsd
		http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.1.xsd
		http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.1.xsd
		http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.1.xsd">

	<!-- Scan for components -->
	<context:component-scan annotation-config="true"
		base-package="org.mitre" />

	<!-- Enables the Spring MVC @Controller programming model -->
	<tx:annotation-driven transaction-manager="transactionManager" />
	<mvc:annotation-driven />
	<mvc:default-servlet-handler />

	<!-- Bean to hold configuration propreties -->
	<import resource="server-config.xml" />

	<!-- Import the data context -->
	<import resource="data-context.xml" />

	<!-- Spring Security configuration -->

	<oauth:resource-server id="resourceServerFilter"
		token-services-ref="defaultOAuth2ProviderTokenService" />

	<security:http pattern="/oauth/token" 
		create-session="stateless"
		authentication-manager-ref="clientAuthenticationManager"
		entry-point-ref="oauthAuthenticationEntryPoint">
		
		<security:intercept-url pattern="/oauth/token" access="IS_AUTHENTICATED_FULLY" />
		<security:anonymous enabled="false" />
		<security:http-basic entry-point-ref="oauthAuthenticationEntryPoint" />
		<!-- include this only if you need to authenticate clients via request parameters -->
		<security:custom-filter ref="clientCredentialsTokenEndpointFilter" before="BASIC_AUTH_FILTER" />
		<security:access-denied-handler ref="oauthAccessDeniedHandler" />
	</security:http>

	<bean id="oauthAuthenticationEntryPoint" class="org.springframework.security.oauth2.provider.error.OAuth2AuthenticationEntryPoint">
		<property name="realmName" value="openidconnect" />
	</bean>

	<!-- SECOAUTH Authorization Server -->
	<oauth:authorization-server 
		client-details-service-ref="defaultOAuth2ClientDetailsEntityService"
		authorization-request-factory-ref="authorizationRequestFactory" 
		token-services-ref="defaultOAuth2ProviderTokenService" 
		user-approval-handler-ref="userApprovalHandler" 
		authorization-endpoint-url="/openidconnect/auth" 
		token-endpoint-url="/openidconnect/token">
		
		<oauth:authorization-code />
		<oauth:implicit />
		
	</oauth:authorization-server>

	<bean id="oauthAccessDeniedHandler" class="org.springframework.security.oauth2.provider.error.OAuth2AccessDeniedHandler" />

	<bean id="clientCredentialsTokenEndpointFilter" class="org.springframework.security.oauth2.provider.client.ClientCredentialsTokenEndpointFilter">
		<property name="authenticationManager" ref="clientAuthenticationManager" />
	</bean>

	<authentication-manager id="clientAuthenticationManager" xmlns="http://www.springframework.org/schema/security">
		<authentication-provider user-service-ref="clientUserDetailsService" />
	</authentication-manager>

	<bean id="authorizationRequestFactory" class="org.springframework.security.oauth2.provider.DefaultAuthorizationRequestFactory">
		<constructor-arg>
			<bean class="org.mitre.oauth2.service.impl.DefaultOAuth2ClientDetailsEntityService" />
		</constructor-arg>
	</bean>

	<bean class="org.springframework.security.oauth2.provider.approval.TokenServicesUserApprovalHandler" id="userApprovalHandler">
		<property name="tokenServices" ref="defaultOAuth2ProviderTokenService" />
	</bean>

	<bean id="authCodeServices" class="org.springframework.security.oauth2.provider.code.InMemoryAuthorizationCodeServices" />

	<!-- user services -->
	<import resource="user-context.xml" />

	<!-- End Spring Security configuration -->

	<!-- JPA -->

	<bean id="jpaAdapter" class="org.springframework.orm.jpa.vendor.EclipseLinkJpaVendorAdapter">
		<property name="databasePlatform" value="org.eclipse.persistence.platform.database.MySQLPlatform" />
		<property name="showSql" value="true" />
	</bean>

	<bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">
		<property name="entityManagerFactory" ref="entityManagerFactory" />
	</bean>

	<bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
		<property name="persistenceUnitName" value="openidPersistenceUnit" />
		<property name="dataSource" ref="dataSource" />
		<property name="jpaVendorAdapter" ref="jpaAdapter" />
		<property name="jpaPropertyMap">
			<map>
				<entry key="eclipselink.weaving" value="false" />
				<entry key="eclipselink.logging.level" value="FINEST" />
				<entry key="eclipselink.logging.level.sql" value="FINEST" />
			</map>
		</property>
	</bean>

	<!-- End JPA -->

	<!-- Crypto -->

	<import resource="crypto-config.xml" />

	<!-- End Crypto -->

	<!-- View configuration -->

	<!-- Handles HTTP GET requests for /resources/** by efficiently serving 
		up static resources in the ${webappRoot}/resources directory -->
	<mvc:resources mapping="/resources/**" location="/resources/" />

	<!-- Resolves views selected for rendering by @Controllers to .jsp resources 
		in the /WEB-INF/views directory -->
	<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
		<property name="viewClass" value="org.springframework.web.servlet.view.JstlView" />
		<property name="prefix" value="/WEB-INF/views/" />
		<property name="suffix" value=".jsp" />
		<property name="order" value="2" />
	</bean>

	<!-- Resolve views based on string names -->
	<bean class="org.springframework.web.servlet.view.BeanNameViewResolver">
		<property name="order" value="1" />
	</bean>

	<!-- JSON views for each type of model object -->
	
	<bean id="jsonOpenIdConfigurationView" class="org.mitre.swd.view.JsonOpenIdConfigurationView" />
	<bean id="jsonSwdResponseView" class="org.mitre.swd.view.SwdResponse" />
	<bean id="jsonXrdResponseView" class="org.mitre.swd.view.XrdJsonResponse" />
	
	<bean id="jwkKeyList" class="org.mitre.openid.connect.view.JwkKeyListView" />

	<bean id="jsonUserInfoView" class="org.mitre.openid.connect.view.JSONUserInfoView" />
	<bean id="pocoUserInfoView" class="org.mitre.openid.connect.view.POCOUserInfoView" />
	<bean id="jsonIdTokenView" class="org.mitre.openid.connect.view.JSONIdTokenView" />
	<bean id="jsonClientView" class="org.mitre.openid.connect.view.JSONClientView" />

	<!-- Map our custom exception classes to named views -->
	<bean name="exceptionAsJSONView" class="org.mitre.openid.connect.view.ExceptionAsJSONView" />

	<bean
		class="org.springframework.web.servlet.handler.SimpleMappingExceptionResolver">
		<property name="exceptionMappings">
			<props>
				<prop key="org.mitre.openid.connect.web.InvalidJwtSignatureException">exceptionAsJSONView</prop>
				<prop key="org.mitre.openid.connect.web.ExpiredTokenException">exceptionAsJSONView</prop>
				<prop key="org.mitre.openid.connect.web.InvalidJwtIssuerException">exceptionAsJSONView</prop>
			</props>
		</property>
	</bean>

	<!-- End view configuration -->

	<!-- scheduled tasks -->
	<!-- <task:scheduler id="taskScheduler" pool-size="10" /> -->
	<!-- <task:executor id="taskExecutor" pool-size="5" /> -->
	<!-- <task:annotation-driven scheduler="taskScheduler" executor="taskExecutor" /> -->

	<!-- import application-local configuration information (such as bean definitions) -->
	<import resource="local-config.xml" />

</beans>
