Skip to content

Commit

Permalink
Merge pull request #333 from jglick/LastGrantedAuthoritiesProperty
Browse files Browse the repository at this point in the history
Replace `OicUserProperty` with `LastGrantedAuthoritiesProperty`
  • Loading branch information
michael-doubez authored Jun 10, 2024
2 parents cac1e2f + bca3705 commit 0cc21de
Show file tree
Hide file tree
Showing 4 changed files with 32 additions and 195 deletions.
84 changes: 26 additions & 58 deletions src/main/java/org/jenkinsci/plugins/oic/OicSecurityRealm.java
Original file line number Diff line number Diff line change
Expand Up @@ -108,9 +108,6 @@
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.security.crypto.bcrypt.BCrypt;

import static org.apache.commons.lang.StringUtils.isNotBlank;
Expand Down Expand Up @@ -776,60 +773,33 @@ public String getAuthenticationGatewayUrl() {
*/
@Override
public SecurityComponents createSecurityComponents() {
return new SecurityComponents(
new AuthenticationManager() {
public Authentication authenticate(Authentication authentication) throws AuthenticationException {
if (authentication instanceof AnonymousAuthenticationToken) return authentication;

if (authentication instanceof UsernamePasswordAuthenticationToken && escapeHatchEnabled) {
randomWait(); // to slowdown brute forcing
if (checkEscapeHatch(
authentication.getPrincipal().toString(),
authentication.getCredentials().toString())) {
List<GrantedAuthority> grantedAuthorities = new ArrayList<>();
grantedAuthorities.add(SecurityRealm.AUTHENTICATED_AUTHORITY2);
if (isNotBlank(escapeHatchGroup)) {
grantedAuthorities.add(new SimpleGrantedAuthority(escapeHatchGroup));
}
UsernamePasswordAuthenticationToken token = new UsernamePasswordAuthenticationToken(
escapeHatchUsername, "", grantedAuthorities);
SecurityContextHolder.getContext().setAuthentication(token);
OicUserDetails userDetails =
new OicUserDetails(escapeHatchUsername, grantedAuthorities);
SecurityListener.fireAuthenticated2(userDetails);
return token;
} else {
throw new BadCredentialsException("Wrong username and password: " + authentication);
}
return new SecurityComponents(new AuthenticationManager() {
public Authentication authenticate(Authentication authentication) throws AuthenticationException {
if (authentication instanceof AnonymousAuthenticationToken) return authentication;

if (authentication instanceof UsernamePasswordAuthenticationToken && escapeHatchEnabled) {
randomWait(); // to slowdown brute forcing
if (checkEscapeHatch(
authentication.getPrincipal().toString(),
authentication.getCredentials().toString())) {
List<GrantedAuthority> grantedAuthorities = new ArrayList<>();
grantedAuthorities.add(SecurityRealm.AUTHENTICATED_AUTHORITY2);
if (isNotBlank(escapeHatchGroup)) {
grantedAuthorities.add(new SimpleGrantedAuthority(escapeHatchGroup));
}
throw new BadCredentialsException("Unexpected authentication type: " + authentication);
UsernamePasswordAuthenticationToken token =
new UsernamePasswordAuthenticationToken(escapeHatchUsername, "", grantedAuthorities);
SecurityContextHolder.getContext().setAuthentication(token);
OicUserDetails userDetails = new OicUserDetails(escapeHatchUsername, grantedAuthorities);

Check warning on line 793 in src/main/java/org/jenkinsci/plugins/oic/OicSecurityRealm.java

View check run for this annotation

ci.jenkins.io / Code Coverage

Not covered lines

Lines 790-793 are not covered by tests
SecurityListener.fireAuthenticated2(userDetails);
return token;
} else {
throw new BadCredentialsException("Wrong username and password: " + authentication);
}
},
new UserDetailsService() {

@Override
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
// Retrieve the OicUserProperty to get the list of groups that has to be set in the
// OicUserDetails object.
LOGGER.fine("loadUserByUsername in createSecurityComponents called, username: " + username);
User u = User.get(username, false, Collections.emptyMap());
if (u == null) {
LOGGER.fine("loadUserByUsername in createSecurityComponents called, no user '" + username
+ "' found");
throw new UsernameNotFoundException(username);
}
LOGGER.fine("loadUserByUsername in createSecurityComponents called, user: " + u);
OicUserProperty oicProp = u.getProperty(OicUserProperty.class);
List<GrantedAuthority> auths = new ArrayList<>();
if (oicProp != null) {
auths = oicProp.getAuthoritiesAsGrantedAuthorities();
LOGGER.fine(
"loadUserByUsername in createSecurityComponents called, oic prop found with username '"
+ oicProp.getUserName() + "', auths size: " + auths.size());
}
return new OicUserDetails(username, auths);
}
});
}
throw new BadCredentialsException("Unexpected authentication type: " + authentication);
}
});
}

/** Build authorization code flow
Expand Down Expand Up @@ -1077,9 +1047,6 @@ private UsernamePasswordAuthenticationToken loginAndSetUserData(
// should not happen
throw new IOException("Cannot set OIDC property on anonymous user");
}
// Store the list of groups in a OicUserProperty so it can be retrieved later for the UserDetails object.
user.addProperty(new OicUserProperty(userName, grantedAuthorities));

String email = determineStringField(emailFieldExpr, idToken, userInfo);
if (email != null) {
user.addProperty(new Mailer.UserProperty(email));
Expand All @@ -1092,6 +1059,7 @@ private UsernamePasswordAuthenticationToken loginAndSetUserData(

OicUserDetails userDetails = new OicUserDetails(userName, grantedAuthorities);
SecurityListener.fireAuthenticated2(userDetails);
SecurityListener.fireLoggedIn(userName);

return token;
}
Expand Down
75 changes: 0 additions & 75 deletions src/main/java/org/jenkinsci/plugins/oic/OicUserProperty.java

This file was deleted.

54 changes: 0 additions & 54 deletions src/test/java/org/jenkinsci/plugins/oic/OicUserPropertyTest.java

This file was deleted.

14 changes: 6 additions & 8 deletions src/test/java/org/jenkinsci/plugins/oic/PluginTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import jenkins.model.Jenkins;
import jenkins.security.LastGrantedAuthoritiesProperty;
import org.acegisecurity.Authentication;
import org.junit.Before;
import org.junit.BeforeClass;
Expand Down Expand Up @@ -1217,7 +1218,7 @@ public void testGroupListFromStringInfoEndpoint() throws Exception {
}

@Test
public void testOicUserPropertyDescriptor() throws Exception {
public void testLastGrantedAuthoritiesProperty() throws Exception {
wireMockRule.resetAll();

KeyPair keyPair = createKeyPair();
Expand Down Expand Up @@ -1261,24 +1262,21 @@ public void testOicUserPropertyDescriptor() throws Exception {
user.getProperty(Mailer.UserProperty.class).getAddress());
assertEquals("User should be in 2 groups", 2, user.getAuthorities().size());

OicUserProperty userProperty = user.getProperty(OicUserProperty.class);
assertEquals("Should be logged-in as " + TEST_USER_USERNAME, TEST_USER_USERNAME, userProperty.getUserName());
LastGrantedAuthoritiesProperty userProperty = user.getProperty(LastGrantedAuthoritiesProperty.class);
assertEquals(
"Property should specify 3 groups (2 + 'authenticated')",
3,
userProperty.getAuthorities().size());
userProperty.getAuthorities2().size());

jenkinsRule.submit(webClient.goTo("me/configure").getFormByName("config"));
user = User.getById(TEST_USER_USERNAME, false);
assertEquals(
"User should still be in 2 groups", 2, user.getAuthorities().size());
userProperty = user.getProperty(OicUserProperty.class);
assertEquals(
"Should still be logged-in as " + TEST_USER_USERNAME, TEST_USER_USERNAME, userProperty.getUserName());
userProperty = user.getProperty(LastGrantedAuthoritiesProperty.class);
assertEquals(
"Property should still specify 3 groups (2 + 'authenticated')",
3,
userProperty.getAuthorities().size());
userProperty.getAuthorities2().size());
}

private void configureWellKnown(String endSessionUrl, String scopesSupported) {
Expand Down

0 comments on commit 0cc21de

Please sign in to comment.