Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add Jackson Support for Objects stored in HttpSession #3812

Closed
wants to merge 64 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
64 commits
Select commit Hold shift + click to select a range
3a6e5be
JSONAssert version property added
jitendra-bisht Mar 30, 2016
434feed
Jackson and JSONAssert dependencies added
jitendra-bisht Apr 5, 2016
cb29035
Jackson2 package added to add mix-in classes for web module
jitendra-bisht Apr 5, 2016
130729d
DefaultCsrfTokenMixin added
jitendra-bisht Apr 5, 2016
774e6fa
DefaultCsrfTokenMixin tests added
jitendra-bisht Apr 5, 2016
a28b65b
Jackson and jsonassert dependencies added
jitendra-bisht Apr 5, 2016
a9393d3
Jackson2 package added to add jackson mixin classes for this module
jitendra-bisht Apr 5, 2016
614cb5b
SimpleGrantedAuthorityMixin class added
jitendra-bisht Apr 5, 2016
731d232
Mixin added for WebAuthenticationDetails
jitendra-bisht Apr 14, 2016
f808de2
Builder class added with private Constructor
jitendra-bisht Apr 14, 2016
79353ce
Mixin added for DefaultSavedRequest
jitendra-bisht Apr 14, 2016
30f42b7
Http Cookie mixins and Deserializer added
jitendra-bisht Apr 14, 2016
16a9104
SecurityContext Tests added
jitendra-bisht Apr 14, 2016
715065c
UsernamePasswordAuthenticationToken mixins, deserializer and test added
jitendra-bisht Apr 14, 2016
a2c41de
User mixin, deserializer and tests added
jitendra-bisht Apr 14, 2016
0df66e4
Unmodifiable tests added
jitendra-bisht Apr 14, 2016
bb95f25
Mixin and Tests added for SimpleGrantedAuthority
jitendra-bisht Apr 14, 2016
1d94aed
Private Constructor added to enabled enable deserialization support
jitendra-bisht Apr 14, 2016
aeb8cb1
AbstractMixinTests added with default ObjectMapper
jitendra-bisht Apr 14, 2016
3e6fcfa
Mixin and tests added for RememberMeAuthenticationToken
jitendra-bisht Apr 14, 2016
14906c9
static methods added to help in building objects hashKey based Authen…
jitendra-bisht Apr 14, 2016
e8c176a
Private constructor added in AnonymousAuthenticationToken to enable j…
jitendra-bisht Apr 14, 2016
5625231
Jackson and JSONAssert dependencies added in cas module
jitendra-bisht Apr 14, 2016
4460f23
Private constructor added to enable jackson deserialization support
jitendra-bisht Apr 14, 2016
d113906
Mixin and tests added for CasAuthenticationToken
jitendra-bisht Apr 14, 2016
e867ce5
Mix-ins added for AssertionImpl and AttributePrincipalImpl classes us…
jitendra-bisht Apr 14, 2016
9cc1a37
Mix-in and tests added for AnonymousAuthenticationToken
jitendra-bisht Apr 14, 2016
b16da66
License header added and indentation changed to tab
jitendra-bisht Apr 14, 2016
26d4e26
License header added and indentation changed to tab
jitendra-bisht Apr 14, 2016
d6d4658
Space indentation removed to tab
jitendra-bisht Apr 14, 2016
1cd5a70
Space indentation removed from UserMixin
jitendra-bisht Apr 14, 2016
0039850
Code formatted single spaces removed added tab indentation
jitendra-bisht Apr 15, 2016
7f576ca
Documentation added for mixin classes in cas module
jitendra-bisht Apr 22, 2016
9afb364
No need of constructor because Deserializer is already registered
jitendra-bisht Apr 22, 2016
993188b
Documentation added in core module mixin classes
jitendra-bisht Apr 22, 2016
04f9c55
Constructor removed because CookieDeserializer already registered
jitendra-bisht Apr 22, 2016
005e263
Documentation added for web module jackson mixin classes
jitendra-bisht Apr 26, 2016
86ac453
Package name corrected
jitendra-bisht Apr 27, 2016
f625580
extra space removed from docs
jitendra-bisht Apr 27, 2016
3d4b84f
Ignore unknown properties configuration added in DefaultSavedRequests…
jitendra-bisht Jul 9, 2016
da104e8
Removed unused import
jitendra-bisht Jul 9, 2016
9fe6ba7
Jackson SimpleModules added in core, web and cas module
jitendra-bisht Jul 9, 2016
effd806
Licence header added in Core and Web Jackson module
jitendra-bisht Jul 11, 2016
3a96358
javadoc @since 4.2 added in new class / methods / constructors
jitendra-bisht Jul 19, 2016
4bc98c6
Constructor parameter changed
jitendra-bisht Jul 19, 2016
043459e
extractHashKey method moved from AbstractAuthenticationToken to child…
jitendra-bisht Jul 20, 2016
785a6b9
Json autodetect info updated, fields visibility marked any to ensure …
jitendra-bisht Jul 25, 2016
f3d0649
Mixin added for SavedCookie class
jitendra-bisht Jul 25, 2016
257c3bd
Externalized ObjectMapper configuration and tests updated
jitendra-bisht Jul 25, 2016
a5e7cd8
Externalized ObjectMapper configuration and updated tests in web and …
jitendra-bisht Jul 25, 2016
1f78c78
SecurityJacksonModules class added to auto register spring security m…
jitendra-bisht Jul 25, 2016
625282b
Naming convention corrected for security module classes
jitendra-bisht Jul 25, 2016
40eedcf
test classes renamed as per project's naming convention
jitendra-bisht Jul 25, 2016
4c84918
tests added when eraseCredential() invoked
jitendra-bisht Jul 25, 2016
74f48f1
tests refactored
jitendra-bisht Jul 25, 2016
c2c152b
JavaDocs updated
jeetmp3 Jul 26, 2016
97af1c3
Unused imports removed
jeetmp3 Jul 26, 2016
3cb4be4
addModules() added to get list of security modules
jeetmp3 Aug 3, 2016
08323a9
extra logs removed
jeetmp3 Aug 9, 2016
efffa78
typo fixed in variable name
jeetmp3 Aug 9, 2016
9e7e2cb
httpOnly field name fixed in CookieDeserializer
jeetmp3 Aug 9, 2016
731c147
Merge branch 'gh-3812'
jeetmp3 Aug 9, 2016
b35f44a
registerModules method replaced with getModules
jeetmp3 Aug 9, 2016
971ad4b
Merge branch 'gh-3812'
jeetmp3 Aug 9, 2016
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 4 additions & 1 deletion cas/cas.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,10 @@ dependencies {
"org.springframework:spring-web:$springVersion",
"org.jasig.cas.client:cas-client-core:$casClientVersion"

optional "net.sf.ehcache:ehcache:$ehcacheVersion"
optional "net.sf.ehcache:ehcache:$ehcacheVersion",
"com.fasterxml.jackson.core:jackson-databind:$jacksonDatavindVersion"

testCompile "org.skyscreamer:jsonassert:$jsonassertVersion"

provided "javax.servlet:javax.servlet-api:$servletApiVersion"
}
Original file line number Diff line number Diff line change
Expand Up @@ -50,37 +50,62 @@ public class CasAuthenticationToken extends AbstractAuthenticationToken implemen
/**
* Constructor.
*
* @param key to identify if this object made by a given
* {@link CasAuthenticationProvider}
* @param principal typically the UserDetails object (cannot be <code>null</code>)
* @param key to identify if this object made by a given
* {@link CasAuthenticationProvider}
* @param principal typically the UserDetails object (cannot be <code>null</code>)
* @param credentials the service/proxy ticket ID from CAS (cannot be
* <code>null</code>)
* <code>null</code>)
* @param authorities the authorities granted to the user (from the
* {@link org.springframework.security.core.userdetails.UserDetailsService}) (cannot
* be <code>null</code>)
* {@link org.springframework.security.core.userdetails.UserDetailsService}) (cannot
* be <code>null</code>)
* @param userDetails the user details (from the
* {@link org.springframework.security.core.userdetails.UserDetailsService}) (cannot
* be <code>null</code>)
* @param assertion the assertion returned from the CAS servers. It contains the
* principal and how to obtain a proxy ticket for the user.
*
* {@link org.springframework.security.core.userdetails.UserDetailsService}) (cannot
* be <code>null</code>)
* @param assertion the assertion returned from the CAS servers. It contains the
* principal and how to obtain a proxy ticket for the user.
* @throws IllegalArgumentException if a <code>null</code> was passed
*/
public CasAuthenticationToken(final String key, final Object principal,
final Object credentials,
final Collection<? extends GrantedAuthority> authorities,
final UserDetails userDetails, final Assertion assertion) {
final Object credentials,
final Collection<? extends GrantedAuthority> authorities,
final UserDetails userDetails, final Assertion assertion) {
this(extractKeyHash(key), principal, credentials, authorities, userDetails, assertion);
}

/**
* Private constructor for Jackson Deserialization support
*
* @param keyHash hashCode of provided key to identify if this object made by a given
* {@link CasAuthenticationProvider}
* @param principal typically the UserDetails object (cannot be <code>null</code>)
* @param credentials the service/proxy ticket ID from CAS (cannot be
* <code>null</code>)
* @param authorities the authorities granted to the user (from the
* {@link org.springframework.security.core.userdetails.UserDetailsService}) (cannot
* be <code>null</code>)
* @param userDetails the user details (from the
* {@link org.springframework.security.core.userdetails.UserDetailsService}) (cannot
* be <code>null</code>)
* @param assertion the assertion returned from the CAS servers. It contains the
* principal and how to obtain a proxy ticket for the user.
* @throws IllegalArgumentException if a <code>null</code> was passed
* @since 4.2
*/
private CasAuthenticationToken(final Integer keyHash, final Object principal,
final Object credentials,
final Collection<? extends GrantedAuthority> authorities,
final UserDetails userDetails, final Assertion assertion) {
super(authorities);

if ((key == null) || ("".equals(key)) || (principal == null)
if ((principal == null)
|| "".equals(principal) || (credentials == null)
|| "".equals(credentials) || (authorities == null)
|| (userDetails == null) || (assertion == null)) {
throw new IllegalArgumentException(
"Cannot pass null or empty values to constructor");
}

this.keyHash = key.hashCode();
this.keyHash = keyHash;
this.principal = principal;
this.credentials = credentials;
this.userDetails = userDetails;
Expand All @@ -91,6 +116,18 @@ public CasAuthenticationToken(final String key, final Object principal,
// ~ Methods
// ========================================================================================================

private static Integer extractKeyHash(String key) {
Object value = nullSafeValue(key);
return value.hashCode();
}

private static Object nullSafeValue(Object value) {
if (value == null || "".equals(value)) {
throw new IllegalArgumentException("Cannot pass null or empty values to constructor");
}
return value;
}

public boolean equals(final Object obj) {
if (!super.equals(obj)) {
return false;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
/*
* Copyright 2015-2016 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package org.springframework.security.cas.jackson2;

import com.fasterxml.jackson.annotation.*;
import org.jasig.cas.client.authentication.AttributePrincipal;

import java.util.Date;
import java.util.Map;

/**
* Helps in jackson deserialization of class {@link org.jasig.cas.client.validation.AssertionImpl}, which is
* used with {@link org.springframework.security.cas.authentication.CasAuthenticationToken}.
* To use this class we need to register with {@link com.fasterxml.jackson.databind.ObjectMapper}. Type information
* will be stored in @class property.
* <p>
* <pre>
* ObjectMapper mapper = new ObjectMapper();
* mapper.registerModule(new CasJackson2Module());
* </pre>
*
*
* @author Jitendra Singh
* @see CasJackson2Module
* @see org.springframework.security.jackson2.SecurityJacksonModules
* @since 4.2
*/
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please add @since 4.2 to all new methods / constructors / classes

@JsonTypeInfo(use = JsonTypeInfo.Id.CLASS, include = JsonTypeInfo.As.PROPERTY)
@JsonAutoDetect(fieldVisibility = JsonAutoDetect.Visibility.ANY,
getterVisibility = JsonAutoDetect.Visibility.NONE, isGetterVisibility = JsonAutoDetect.Visibility.NONE)
@JsonIgnoreProperties(ignoreUnknown = true)
public class AssertionImplMixin {

/**
* Mixin Constructor helps in deserialize {@link org.jasig.cas.client.validation.AssertionImpl}
*
* @param principal the Principal to associate with the Assertion.
* @param validFromDate when the assertion is valid from.
* @param validUntilDate when the assertion is valid to.
* @param authenticationDate when the assertion is authenticated.
* @param attributes the key/value pairs for this attribute.
*/
@JsonCreator
public AssertionImplMixin(@JsonProperty("principal") AttributePrincipal principal,
@JsonProperty("validFromDate") Date validFromDate, @JsonProperty("validUntilDate") Date validUntilDate,
@JsonProperty("authenticationDate") Date authenticationDate, @JsonProperty("attributes") Map<String, Object> attributes){
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
/*
* Copyright 2015-2016 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package org.springframework.security.cas.jackson2;

import com.fasterxml.jackson.annotation.*;
import org.jasig.cas.client.proxy.ProxyRetriever;

import java.util.Map;

/**
* Helps in deserialize {@link org.jasig.cas.client.authentication.AttributePrincipalImpl} which is used with
* {@link org.springframework.security.cas.authentication.CasAuthenticationToken}. Type information will be stored
* in property named @class.
* <p>
* <pre>
* ObjectMapper mapper = new ObjectMapper();
* mapper.registerModule(new CasJackson2Module());
* </pre>
*
* @author Jitendra Singh
* @see CasJackson2Module
* @see org.springframework.security.jackson2.SecurityJacksonModules
* @since 4.2
*/
@JsonTypeInfo(use = JsonTypeInfo.Id.CLASS, include = JsonTypeInfo.As.PROPERTY)
@JsonAutoDetect(fieldVisibility = JsonAutoDetect.Visibility.ANY, getterVisibility = JsonAutoDetect.Visibility.NONE,
isGetterVisibility = JsonAutoDetect.Visibility.NONE)
@JsonIgnoreProperties(ignoreUnknown = true)
public class AttributePrincipalImplMixin {

/**
* Mixin Constructor helps in deserialize {@link org.jasig.cas.client.authentication.AttributePrincipalImpl}
*
* @param name the unique identifier for the principal.
* @param attributes the key/value pairs for this principal.
* @param proxyGrantingTicket the ticket associated with this principal.
* @param proxyRetriever the ProxyRetriever implementation to call back to the CAS server.
*/
@JsonCreator
public AttributePrincipalImplMixin(@JsonProperty("name") String name, @JsonProperty("attributes") Map<String, Object> attributes,
@JsonProperty("proxyGrantingTicket") String proxyGrantingTicket,
@JsonProperty("proxyRetriever") ProxyRetriever proxyRetriever) {
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
/*
* Copyright 2015-2016 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package org.springframework.security.cas.jackson2;

import com.fasterxml.jackson.annotation.*;
import org.jasig.cas.client.validation.Assertion;
import org.springframework.security.cas.authentication.CasAuthenticationProvider;
import org.springframework.security.cas.authentication.CasAuthenticationToken;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.userdetails.UserDetails;

import java.util.Collection;

/**
* Mixin class which helps in deserialize {@link org.springframework.security.cas.authentication.CasAuthenticationToken}
* using jackson. Two more dependent classes needs to register along with this mixin class.
* <ol>
* <li>{@link org.springframework.security.cas.jackson2.AssertionImplMixin}</li>
* <li>{@link org.springframework.security.cas.jackson2.AttributePrincipalImplMixin}</li>
* </ol>
*
* <p>
*
* <pre>
* ObjectMapper mapper = new ObjectMapper();
* mapper.registerModule(new CasJackson2Module());
* </pre>
*
* @author Jitendra Singh
* @see CasJackson2Module
* @see org.springframework.security.jackson2.SecurityJacksonModules
* @since 4.2
*/
@JsonTypeInfo(use = JsonTypeInfo.Id.CLASS, include = JsonTypeInfo.As.PROPERTY)
@JsonAutoDetect(fieldVisibility = JsonAutoDetect.Visibility.ANY, isGetterVisibility = JsonAutoDetect.Visibility.NONE,
getterVisibility = JsonAutoDetect.Visibility.NONE, creatorVisibility = JsonAutoDetect.Visibility.ANY)
@JsonIgnoreProperties(ignoreUnknown = true)
public class CasAuthenticationTokenMixin {

/**
* Mixin Constructor helps in deserialize {@link CasAuthenticationToken}
*
* @param keyHash hashCode of provided key to identify if this object made by a given
* {@link CasAuthenticationProvider}
* @param principal typically the UserDetails object (cannot be <code>null</code>)
* @param credentials the service/proxy ticket ID from CAS (cannot be
* <code>null</code>)
* @param authorities the authorities granted to the user (from the
* {@link org.springframework.security.core.userdetails.UserDetailsService}) (cannot
* be <code>null</code>)
* @param userDetails the user details (from the
* {@link org.springframework.security.core.userdetails.UserDetailsService}) (cannot
* be <code>null</code>)
* @param assertion the assertion returned from the CAS servers. It contains the
* principal and how to obtain a proxy ticket for the user.
*/
@JsonCreator
public CasAuthenticationTokenMixin(@JsonProperty("keyHash") Integer keyHash, @JsonProperty("principal") Object principal,
@JsonProperty("credentials") Object credentials,
@JsonProperty("authorities") Collection<? extends GrantedAuthority> authorities,
@JsonProperty("userDetails") UserDetails userDetails, @JsonProperty("assertion") Assertion assertion) {
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
/*
* Copyright 2015-2016 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package org.springframework.security.cas.jackson2;

import com.fasterxml.jackson.core.Version;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.module.SimpleModule;
import org.jasig.cas.client.authentication.AttributePrincipalImpl;
import org.jasig.cas.client.validation.AssertionImpl;
import org.springframework.security.cas.authentication.CasAuthenticationToken;
import org.springframework.security.jackson2.SecurityJacksonModules;

/**
* Jackson module for spring-security-cas. This module register {@link AssertionImplMixin},
* {@link AttributePrincipalImplMixin} and {@link CasAuthenticationTokenMixin}. If no default typing enabled by default then
* it'll enable it because typing info is needed to properly serialize/deserialize objects. In order to use this module just
* add this module into your ObjectMapper configuration.
*
* <pre>
* ObjectMapper mapper = new ObjectMapper();
* mapper.registerModule(new CasJackson2Module());
* </pre>
* <b>Note: use {@link SecurityJacksonModules#getModules()} to get list of all security modules.</b>
*
* @author Jitendra Singh.
* @see org.springframework.security.jackson2.SecurityJacksonModules
* @since 4.2
*/
public class CasJackson2Module extends SimpleModule {

public CasJackson2Module() {
super(CasJackson2Module.class.getName(), new Version(1, 0, 0, null, null, null));
}

@Override
public void setupModule(SetupContext context) {
SecurityJacksonModules.enableDefaultTyping((ObjectMapper) context.getOwner());
context.setMixInAnnotations(AssertionImpl.class, AssertionImplMixin.class);
context.setMixInAnnotations(AttributePrincipalImpl.class, AttributePrincipalImplMixin.class);
context.setMixInAnnotations(CasAuthenticationToken.class, CasAuthenticationTokenMixin.class);
}
}
Loading