Skip to content

Commit 71e491f

Browse files
committed
Provide abstraction for an Authenticated Principal
1 parent 2ce174d commit 71e491f

File tree

5 files changed

+157
-6
lines changed

5 files changed

+157
-6
lines changed

core/src/main/java/org/springframework/security/authentication/AbstractAuthenticationToken.java

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -24,8 +24,8 @@
2424
import org.springframework.security.core.Authentication;
2525
import org.springframework.security.core.GrantedAuthority;
2626
import org.springframework.security.core.CredentialsContainer;
27+
import org.springframework.security.core.AuthenticatedPrincipal;
2728
import org.springframework.security.core.authority.AuthorityUtils;
28-
import org.springframework.security.core.userdetails.UserDetails;
2929

3030
/**
3131
* Base class for <code>Authentication</code> objects.
@@ -79,8 +79,8 @@ public Collection<GrantedAuthority> getAuthorities() {
7979
}
8080

8181
public String getName() {
82-
if (this.getPrincipal() instanceof UserDetails) {
83-
return ((UserDetails) this.getPrincipal()).getUsername();
82+
if (this.getPrincipal() instanceof AuthenticatedPrincipal) {
83+
return ((AuthenticatedPrincipal) this.getPrincipal()).getName();
8484
}
8585

8686
if (getPrincipal() instanceof Principal) {
Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
/*
2+
* Copyright 2012-2017 the original author or authors.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
package org.springframework.security.core;
17+
18+
import org.springframework.security.authentication.AuthenticationManager;
19+
20+
/**
21+
* Representation of an authenticated <code>Principal</code> once an
22+
* {@link Authentication} request has been successfully authenticated
23+
* by the {@link AuthenticationManager#authenticate(Authentication)} method.
24+
*
25+
* Implementors typically provide their own representation of a <code>Principal</code>,
26+
* which usually contains information describing the <code>Principal</code> entity,
27+
* such as, first/middle/last name, address, email, phone, id, etc.
28+
*
29+
* This interface allows implementors to expose specific attributes
30+
* of their custom representation of <code>Principal</code> in a generic way.
31+
*
32+
* @author Joe Grandja
33+
* @since 5.0
34+
* @see Authentication#getPrincipal()
35+
* @see org.springframework.security.core.userdetails.UserDetails
36+
*/
37+
public interface AuthenticatedPrincipal {
38+
39+
/**
40+
* Returns the name of the authenticated <code>Principal</code>. Never <code>null</code>.
41+
*
42+
* @return the name of the authenticated <code>Principal</code>
43+
*/
44+
String getName();
45+
46+
}

core/src/main/java/org/springframework/security/core/userdetails/UserDetails.java

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818

1919
import org.springframework.security.core.Authentication;
2020
import org.springframework.security.core.GrantedAuthority;
21+
import org.springframework.security.core.AuthenticatedPrincipal;
2122

2223
import java.io.Serializable;
2324
import java.util.Collection;
@@ -41,7 +42,7 @@
4142
*
4243
* @author Ben Alex
4344
*/
44-
public interface UserDetails extends Serializable {
45+
public interface UserDetails extends AuthenticatedPrincipal, Serializable {
4546
// ~ Methods
4647
// ========================================================================================================
4748

@@ -60,8 +61,7 @@ public interface UserDetails extends Serializable {
6061
String getPassword();
6162

6263
/**
63-
* Returns the username used to authenticate the user. Cannot return <code>null</code>
64-
* .
64+
* Returns the username used to authenticate the user. Cannot return <code>null</code>.
6565
*
6666
* @return the username (never <code>null</code>)
6767
*/
@@ -100,4 +100,14 @@ public interface UserDetails extends Serializable {
100100
* @return <code>true</code> if the user is enabled, <code>false</code> otherwise
101101
*/
102102
boolean isEnabled();
103+
104+
/**
105+
* Returns the name of the user. Cannot return <code>null</code>.
106+
* The default implementation of this method returns {@link #getUsername()}.
107+
*
108+
* @return the name of the user (never <code>null</code>)
109+
*/
110+
default String getName() {
111+
return getUsername();
112+
}
103113
}

core/src/test/java/org/springframework/security/authentication/AbstractAuthenticationTokenTests.java

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,8 +17,10 @@
1717
package org.springframework.security.authentication;
1818

1919
import static org.assertj.core.api.Assertions.*;
20+
import static org.mockito.Mockito.*;
2021

2122
import org.junit.*;
23+
import org.springframework.security.core.AuthenticatedPrincipal;
2224
import org.springframework.security.core.GrantedAuthority;
2325
import org.springframework.security.core.authority.AuthorityUtils;
2426
import org.springframework.security.core.authority.SimpleGrantedAuthority;
@@ -135,6 +137,18 @@ public void testToStringWithNullAuthorities() {
135137
assertThat(token.toString().lastIndexOf("Not granted any authorities") != -1).isTrue();
136138
}
137139

140+
@Test
141+
public void testGetNameWhenPrincipalIsAuthenticatedPrincipal() {
142+
String principalName = "test";
143+
144+
AuthenticatedPrincipal principal = mock(AuthenticatedPrincipal.class);
145+
when(principal.getName()).thenReturn(principalName);
146+
147+
MockAuthenticationImpl token = new MockAuthenticationImpl(principal, "Password", authorities);
148+
assertThat(token.getName()).isEqualTo(principalName);
149+
verify(principal, times(1)).getName();
150+
}
151+
138152
// ~ Inner Classes
139153
// ==================================================================================================
140154

Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
1+
/*
2+
* Copyright 2012-2017 the original author or authors.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
package org.springframework.security.core.userdetails;
17+
18+
import org.junit.Test;
19+
import org.springframework.security.core.GrantedAuthority;
20+
import org.springframework.security.core.authority.AuthorityUtils;
21+
22+
import java.util.Collection;
23+
24+
import static org.assertj.core.api.Assertions.assertThat;
25+
26+
/**
27+
* Tests {@link UserDetails}
28+
*
29+
* @author Joe Grandja
30+
*/
31+
public class UserDetailsTest {
32+
33+
@Test
34+
public void getNameWhenCalledThenDefaultToGetUsername() {
35+
UserDetails userDetails = new MockUserDetails("joeg");
36+
assertThat(userDetails.getName()).isEqualTo(userDetails.getUsername());
37+
}
38+
39+
private class MockUserDetails implements UserDetails {
40+
private final String username;
41+
42+
private MockUserDetails(String username) {
43+
this.username = username;
44+
}
45+
46+
@Override
47+
public Collection<? extends GrantedAuthority> getAuthorities() {
48+
return AuthorityUtils.NO_AUTHORITIES;
49+
}
50+
51+
@Override
52+
public String getPassword() {
53+
return null;
54+
}
55+
56+
@Override
57+
public String getUsername() {
58+
return this.username;
59+
}
60+
61+
@Override
62+
public boolean isAccountNonExpired() {
63+
return true;
64+
}
65+
66+
@Override
67+
public boolean isAccountNonLocked() {
68+
return true;
69+
}
70+
71+
@Override
72+
public boolean isCredentialsNonExpired() {
73+
return true;
74+
}
75+
76+
@Override
77+
public boolean isEnabled() {
78+
return true;
79+
}
80+
}
81+
}

0 commit comments

Comments
 (0)