Skip to content

Commit c82ceae

Browse files
author
Juraj Veverka
committed
implemented user roles and security context support
1 parent 11dd552 commit c82ceae

10 files changed

Lines changed: 210 additions & 22 deletions

File tree

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
package itx.examples.springboot.security.springsecurity.config;
2+
3+
import itx.examples.springboot.security.springsecurity.services.dto.RoleId;
4+
import org.springframework.security.core.Authentication;
5+
import org.springframework.security.core.GrantedAuthority;
6+
7+
import java.util.ArrayList;
8+
import java.util.Collection;
9+
import java.util.Collections;
10+
import java.util.List;
11+
import java.util.Set;
12+
13+
public class AuthenticationImpl implements Authentication {
14+
15+
private final String name;
16+
private final Collection<GrantedAuthorityImpl> grantedAuthorities;
17+
18+
public AuthenticationImpl(String name, Set<RoleId> roles) {
19+
this.name = name;
20+
List<GrantedAuthorityImpl> authorities = new ArrayList<>();
21+
roles.forEach(r->{
22+
authorities.add(new GrantedAuthorityImpl(r.getId()));
23+
});
24+
this.grantedAuthorities = Collections.unmodifiableCollection(authorities);
25+
}
26+
27+
28+
@Override
29+
public Collection<? extends GrantedAuthority> getAuthorities() {
30+
return grantedAuthorities;
31+
}
32+
33+
@Override
34+
public Object getCredentials() {
35+
return null;
36+
}
37+
38+
@Override
39+
public Object getDetails() {
40+
return null;
41+
}
42+
43+
@Override
44+
public Object getPrincipal() {
45+
return null;
46+
}
47+
48+
@Override
49+
public boolean isAuthenticated() {
50+
return true;
51+
}
52+
53+
@Override
54+
public void setAuthenticated(boolean isAuthenticated) throws IllegalArgumentException {
55+
56+
}
57+
58+
@Override
59+
public String getName() {
60+
return name;
61+
}
62+
}
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
package itx.examples.springboot.security.springsecurity.config;
2+
3+
import org.springframework.security.core.GrantedAuthority;
4+
5+
public class GrantedAuthorityImpl implements GrantedAuthority {
6+
7+
private final String authority;
8+
9+
public GrantedAuthorityImpl(String authority) {
10+
this.authority = authority;
11+
}
12+
13+
@Override
14+
public String getAuthority() {
15+
return authority;
16+
}
17+
}

spring/spring-security/src/main/java/itx/examples/springboot/security/springsecurity/config/SecurityFilter.java

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,12 @@
11
package itx.examples.springboot.security.springsecurity.config;
22

33
import itx.examples.springboot.security.springsecurity.services.UserAccessService;
4+
import itx.examples.springboot.security.springsecurity.services.dto.UserData;
45
import org.slf4j.Logger;
56
import org.slf4j.LoggerFactory;
67
import org.springframework.http.HttpStatus;
8+
import org.springframework.security.core.context.SecurityContext;
9+
import org.springframework.security.core.context.SecurityContextHolder;
710

811
import javax.servlet.Filter;
912
import javax.servlet.FilterChain;
@@ -12,7 +15,9 @@
1215
import javax.servlet.ServletResponse;
1316
import javax.servlet.http.HttpServletRequest;
1417
import javax.servlet.http.HttpServletResponse;
18+
import javax.servlet.http.HttpSession;
1519
import java.io.IOException;
20+
import java.util.Optional;
1621

1722
public class SecurityFilter implements Filter {
1823

@@ -28,7 +33,12 @@ public SecurityFilter(UserAccessService userAccessService) {
2833
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
2934
HttpServletRequest httpServletRequest = (HttpServletRequest)request;
3035
String sessionId = httpServletRequest.getSession(true).getId();
31-
if (userAccessService.isAuthorized(sessionId)) {
36+
Optional<UserData> userData = userAccessService.isAuthorized(sessionId);
37+
if (userData.isPresent()) {
38+
SecurityContext securityContext = SecurityContextHolder.getContext();
39+
securityContext.setAuthentication(new AuthenticationImpl(userData.get().getUserName(), userData.get().getRoles()));
40+
HttpSession session = httpServletRequest.getSession();
41+
session.setAttribute("SPRING_SECURITY_CONTEXT", securityContext);
3242
chain.doFilter(request, response);
3343
} else {
3444
LOG.error("session is not authorized: {}", sessionId);

spring/spring-security/src/main/java/itx/examples/springboot/security/springsecurity/rest/DataResource.java renamed to spring/spring-security/src/main/java/itx/examples/springboot/security/springsecurity/rest/DataRestController.java

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,22 +2,34 @@
22

33
import itx.examples.springboot.security.springsecurity.services.DataService;
44
import itx.examples.springboot.security.springsecurity.services.dto.ServerData;
5+
import org.slf4j.Logger;
6+
import org.slf4j.LoggerFactory;
57
import org.springframework.beans.factory.annotation.Autowired;
68
import org.springframework.http.ResponseEntity;
9+
import org.springframework.security.core.context.SecurityContext;
10+
import org.springframework.security.core.context.SecurityContextHolder;
711
import org.springframework.web.bind.annotation.GetMapping;
812
import org.springframework.web.bind.annotation.RequestMapping;
913
import org.springframework.web.bind.annotation.RestController;
1014

15+
1116
@RestController
1217
@RequestMapping("/services/data/")
13-
public class DataResource {
18+
public class DataRestController {
19+
20+
private static final Logger LOG = LoggerFactory.getLogger(DataRestController.class);
1421

1522
@Autowired
1623
private DataService dataService;
1724

1825
@GetMapping("/all")
1926
public ResponseEntity<ServerData> getData() {
20-
return ResponseEntity.ok().body(dataService.getSecuredData("Secured"));
27+
SecurityContext securityContext = SecurityContextHolder.getContext();
28+
LOG.info("getData: authentication={}", securityContext.getAuthentication().getName());
29+
securityContext.getAuthentication().getAuthorities().forEach(a->{
30+
LOG.info("authority={}", a.getAuthority());
31+
});
32+
return ResponseEntity.ok().body(dataService.getSecuredData("Secured for " + securityContext.getAuthentication().getName()));
2133
}
2234

2335
}

spring/spring-security/src/main/java/itx/examples/springboot/security/springsecurity/rest/PublicResource.java renamed to spring/spring-security/src/main/java/itx/examples/springboot/security/springsecurity/rest/PublicRestController.java

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@
22

33
import itx.examples.springboot.security.springsecurity.services.DataService;
44
import itx.examples.springboot.security.springsecurity.services.dto.ServerData;
5+
import org.slf4j.Logger;
6+
import org.slf4j.LoggerFactory;
57
import org.springframework.beans.factory.annotation.Autowired;
68
import org.springframework.http.ResponseEntity;
79
import org.springframework.web.bind.annotation.GetMapping;
@@ -10,13 +12,16 @@
1012

1113
@RestController
1214
@RequestMapping("/services/public/")
13-
public class PublicResource {
15+
public class PublicRestController {
16+
17+
private static final Logger LOG = LoggerFactory.getLogger(PublicRestController.class);
1418

1519
@Autowired
1620
private DataService dataService;
1721

1822
@GetMapping("/all")
1923
public ResponseEntity<ServerData> getData() {
24+
LOG.info("getData: ");
2025
return ResponseEntity.ok().body(dataService.getSecuredData("Public"));
2126
}
2227

spring/spring-security/src/main/java/itx/examples/springboot/security/springsecurity/rest/SecurityResource.java renamed to spring/spring-security/src/main/java/itx/examples/springboot/security/springsecurity/rest/SecurityRestController.java

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
import itx.examples.springboot.security.springsecurity.services.UserAccessService;
44
import itx.examples.springboot.security.springsecurity.services.dto.LoginRequest;
5+
import itx.examples.springboot.security.springsecurity.services.dto.UserData;
56
import org.springframework.beans.factory.annotation.Autowired;
67
import org.springframework.http.HttpStatus;
78
import org.springframework.http.ResponseEntity;
@@ -12,10 +13,11 @@
1213
import org.springframework.web.bind.annotation.RestController;
1314

1415
import javax.servlet.http.HttpSession;
16+
import java.util.Optional;
1517

1618
@RestController
1719
@RequestMapping("/services/security/")
18-
public class SecurityResource {
20+
public class SecurityRestController {
1921

2022
@Autowired
2123
private UserAccessService userAccessService;
@@ -24,9 +26,10 @@ public class SecurityResource {
2426
private HttpSession httpSession;
2527

2628
@PostMapping("/login")
27-
public ResponseEntity login(@RequestBody LoginRequest loginRequest) {
28-
if (userAccessService.login(httpSession.getId(), loginRequest)) {
29-
return ResponseEntity.ok().build();
29+
public ResponseEntity<UserData> login(@RequestBody LoginRequest loginRequest) {
30+
Optional<UserData> userData = userAccessService.login(httpSession.getId(), loginRequest);
31+
if (userData.isPresent()) {
32+
return ResponseEntity.ok().body(userData.get());
3033
}
3134
return ResponseEntity.status(HttpStatus.FORBIDDEN).build();
3235
}

spring/spring-security/src/main/java/itx/examples/springboot/security/springsecurity/services/UserAccessService.java

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,15 @@
11
package itx.examples.springboot.security.springsecurity.services;
22

33
import itx.examples.springboot.security.springsecurity.services.dto.LoginRequest;
4+
import itx.examples.springboot.security.springsecurity.services.dto.UserData;
5+
6+
import java.util.Optional;
47

58
public interface UserAccessService {
69

7-
boolean login(String sessionId, LoginRequest loginRequest);
10+
Optional<UserData> login(String sessionId, LoginRequest loginRequest);
811

9-
boolean isAuthorized(String sessionId);
12+
Optional<UserData> isAuthorized(String sessionId);
1013

1114
void logout(String sessionId);
1215

spring/spring-security/src/main/java/itx/examples/springboot/security/springsecurity/services/UserAccessServiceImpl.java

Lines changed: 14 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,44 +1,46 @@
11
package itx.examples.springboot.security.springsecurity.services;
22

33
import itx.examples.springboot.security.springsecurity.services.dto.LoginRequest;
4+
import itx.examples.springboot.security.springsecurity.services.dto.UserData;
45
import org.slf4j.Logger;
56
import org.slf4j.LoggerFactory;
67
import org.springframework.stereotype.Service;
78

89
import java.util.HashMap;
910
import java.util.Map;
11+
import java.util.Optional;
1012
import java.util.concurrent.ConcurrentHashMap;
1113

1214
@Service
1315
public class UserAccessServiceImpl implements UserAccessService {
1416

1517
private static final Logger LOG = LoggerFactory.getLogger(UserAccessServiceImpl.class);
1618

17-
private final Map<String, LoginRequest> sessions;
18-
private final Map<String, String> users;
19+
private final Map<String, UserData> sessions;
20+
private final Map<String, UserData> users;
1921

2022
public UserAccessServiceImpl() {
2123
this.sessions = new ConcurrentHashMap<>();
2224
this.users = new HashMap<>();
23-
this.users.put("joe", "secret");
24-
this.users.put("jane", "secret");
25+
this.users.put("joe", new UserData("joe", "secret", "USER"));
26+
this.users.put("jane", new UserData("jane", "secret", "ADMIN", "USER"));
2527
}
2628

2729
@Override
28-
public boolean login(String sessionId, LoginRequest loginRequest) {
29-
String password = users.get(loginRequest.getUserName());
30-
if (password != null && password.equals(loginRequest.getPassword())) {
30+
public Optional<UserData> login(String sessionId, LoginRequest loginRequest) {
31+
UserData userData = users.get(loginRequest.getUserName());
32+
if (userData != null && userData.verifyPassword(loginRequest.getPassword())) {
3133
LOG.info("login OK: {} {}", sessionId, loginRequest.getUserName());
32-
sessions.put(sessionId, loginRequest);
33-
return true;
34+
sessions.put(sessionId, userData);
35+
return Optional.of(userData);
3436
}
3537
LOG.info("login Failed: {} {}", sessionId, loginRequest.getUserName());
36-
return false;
38+
return Optional.empty();
3739
}
3840

3941
@Override
40-
public boolean isAuthorized(String sessionId) {
41-
return sessions.get(sessionId)!=null ? true : false;
42+
public Optional<UserData> isAuthorized(String sessionId) {
43+
return Optional.ofNullable(sessions.get(sessionId));
4244
}
4345

4446
@Override
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
package itx.examples.springboot.security.springsecurity.services.dto;
2+
3+
import java.util.Objects;
4+
5+
public class RoleId {
6+
7+
private final String id;
8+
9+
public RoleId(String id) {
10+
this.id = id;
11+
}
12+
13+
public String getId() {
14+
return id;
15+
}
16+
17+
@Override
18+
public boolean equals(Object o) {
19+
if (this == o) return true;
20+
if (o == null || getClass() != o.getClass()) return false;
21+
RoleId roleId = (RoleId) o;
22+
return Objects.equals(id, roleId.id);
23+
}
24+
25+
@Override
26+
public int hashCode() {
27+
return Objects.hash(id);
28+
}
29+
30+
@Override
31+
public String toString() {
32+
return id;
33+
}
34+
35+
}
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
package itx.examples.springboot.security.springsecurity.services.dto;
2+
3+
import java.util.HashSet;
4+
import java.util.Set;
5+
6+
public class UserData {
7+
8+
private final String userName;
9+
private final String password;
10+
private final Set<RoleId> roles;
11+
12+
public UserData(String userName, String password, Set<RoleId> roles) {
13+
this.userName = userName;
14+
this.password = password;
15+
this.roles = roles;
16+
}
17+
18+
public UserData(String userName, String password, String ... roles) {
19+
this.userName = userName;
20+
this.password = password;
21+
this.roles = new HashSet<>();
22+
for (String role: roles) {
23+
this.roles.add(new RoleId(role));
24+
}
25+
}
26+
27+
public String getUserName() {
28+
return userName;
29+
}
30+
31+
public boolean verifyPassword(String password) {
32+
return this.password.equals(password);
33+
}
34+
35+
public Set<RoleId> getRoles() {
36+
return roles;
37+
}
38+
39+
}

0 commit comments

Comments
 (0)