22
33import java .util .ArrayList ;
44import java .util .Collection ;
5+ import java .util .Collections ;
56import java .util .HashMap ;
67import java .util .Map ;
78import org .springframework .security .core .GrantedAuthority ;
@@ -60,15 +61,27 @@ public class DSUserDetails implements UserDetails, OidcUser {
6061 private OidcIdToken oidcIdToken ;
6162
6263 /**
63- * Instantiates a new DS user details.
64+ * Instantiates a new DS user details with OAuth2 provider attributes .
6465 *
6566 * @param user the user
6667 * @param grantedAuthorities the granted authorities (optional, default = empty list)
68+ * @param attributes the OAuth2 provider attributes (optional, falls back to User entity fields)
6769 */
68- public DSUserDetails (User user , Collection <? extends GrantedAuthority > grantedAuthorities ) {
70+ public DSUserDetails (User user , Collection <? extends GrantedAuthority > grantedAuthorities , Map < String , Object > attributes ) {
6971 this .user = user ;
7072 this .grantedAuthorities = grantedAuthorities != null ? grantedAuthorities : new ArrayList <>();
71- this .attributes = new HashMap <>();
73+ this .attributes = attributes != null ? new HashMap <>(attributes ) : buildFallbackAttributes (user );
74+ }
75+
76+ /**
77+ * Instantiates a new DS user details without provider attributes. Attributes will be populated
78+ * from the {@link User} entity fields as a fallback.
79+ *
80+ * @param user the user
81+ * @param grantedAuthorities the granted authorities (optional, default = empty list)
82+ */
83+ public DSUserDetails (User user , Collection <? extends GrantedAuthority > grantedAuthorities ) {
84+ this (user , grantedAuthorities , (Map <String , Object >) null );
7285 }
7386
7487 /**
@@ -77,35 +90,91 @@ public DSUserDetails(User user, Collection<? extends GrantedAuthority> grantedAu
7790 * @param user the user
7891 */
7992 public DSUserDetails (User user ) {
80- this (user , null );
93+ this (user , null , ( Map < String , Object >) null );
8194 }
8295
8396 /**
84- * Instantiates a new DS user details.
97+ * Instantiates a new DS user details with OIDC tokens and provider attributes .
8598 *
8699 * @param user the user
87100 * @param oidcUserInfo containing claims about the user
88101 * @param oidcIdToken containing claims about the user
89102 * @param grantedAuthorities the granted authorities (optional, default = empty list)
103+ * @param attributes the OAuth2/OIDC provider attributes (optional, falls back to idToken claims or User entity)
90104 */
91105 @ Builder
92- public DSUserDetails (User user , OidcUserInfo oidcUserInfo , OidcIdToken oidcIdToken , Collection <? extends GrantedAuthority > grantedAuthorities ) {
106+ public DSUserDetails (User user , OidcUserInfo oidcUserInfo , OidcIdToken oidcIdToken ,
107+ Collection <? extends GrantedAuthority > grantedAuthorities , Map <String , Object > attributes ) {
93108 this .user = user ;
94109 this .oidcUserInfo = oidcUserInfo ;
95110 this .oidcIdToken = oidcIdToken ;
96111 this .grantedAuthorities = grantedAuthorities != null ? grantedAuthorities : new ArrayList <>();
112+ if (attributes != null ) {
113+ this .attributes = new HashMap <>(attributes );
114+ } else if (oidcIdToken != null ) {
115+ this .attributes = new HashMap <>(oidcIdToken .getClaims ());
116+ } else {
117+ this .attributes = buildFallbackAttributes (user );
118+ }
97119 }
98120
99121 /**
100- * Instantiates a new DS user details.
122+ * Instantiates a new DS user details with OIDC tokens. Attributes will be populated from the
123+ * OIDC ID token claims or {@link User} entity as a fallback.
124+ *
125+ * @param user the user
126+ * @param oidcUserInfo containing claims about the user
127+ * @param oidcIdToken containing claims about the user
128+ * @param grantedAuthorities the granted authorities (optional, default = empty list)
129+ */
130+ public DSUserDetails (User user , OidcUserInfo oidcUserInfo , OidcIdToken oidcIdToken ,
131+ Collection <? extends GrantedAuthority > grantedAuthorities ) {
132+ this (user , oidcUserInfo , oidcIdToken , grantedAuthorities , null );
133+ }
134+
135+ /**
136+ * Instantiates a new DS user details with OIDC tokens and no authorities.
101137 *
102138 * @param user the user
103139 * @param oidcUserInfo containing claims about the user
104140 * @param oidcIdToken containing claims about the user
105141 */
106- @ Builder
107142 public DSUserDetails (User user , OidcUserInfo oidcUserInfo , OidcIdToken oidcIdToken ) {
108- this (user , oidcUserInfo , oidcIdToken , null );
143+ this (user , oidcUserInfo , oidcIdToken , null , null );
144+ }
145+
146+ /**
147+ * Builds a fallback attributes map from the {@link User} entity fields. Used when no provider
148+ * attributes are available (e.g., local/password login).
149+ *
150+ * @param user the user entity
151+ * @return a map containing available user fields using standard OAuth2/OIDC claim names
152+ */
153+ private static Map <String , Object > buildFallbackAttributes (User user ) {
154+ Map <String , Object > attrs = new HashMap <>();
155+ if (user .getEmail () != null ) {
156+ attrs .put ("email" , user .getEmail ());
157+ }
158+ if (user .getFirstName () != null ) {
159+ attrs .put ("given_name" , user .getFirstName ());
160+ }
161+ if (user .getLastName () != null ) {
162+ attrs .put ("family_name" , user .getLastName ());
163+ }
164+ StringBuilder name = new StringBuilder ();
165+ if (user .getFirstName () != null && !user .getFirstName ().trim ().isEmpty ()) {
166+ name .append (user .getFirstName ().trim ());
167+ }
168+ if (user .getLastName () != null && !user .getLastName ().trim ().isEmpty ()) {
169+ if (name .length () > 0 ) {
170+ name .append (' ' );
171+ }
172+ name .append (user .getLastName ().trim ());
173+ }
174+ if (name .length () > 0 ) {
175+ attrs .put ("name" , name .toString ());
176+ }
177+ return attrs ;
109178 }
110179
111180 /**
@@ -189,7 +258,7 @@ public User getUser() {
189258
190259 @ Override
191260 public Map <String , Object > getAttributes () {
192- return attributes ;
261+ return Collections . unmodifiableMap ( attributes ) ;
193262 }
194263
195264 @ Override
0 commit comments