Protected admin section
This commit is contained in:
parent
3b52882037
commit
525d33ed01
.gitignorepom.xml
src
main
test/java/se/su/dsv/oauth2/web
1
.gitignore
vendored
1
.gitignore
vendored
@ -4,6 +4,7 @@ target/
|
|||||||
!**/src/main/**/target/
|
!**/src/main/**/target/
|
||||||
!**/src/test/**/target/
|
!**/src/test/**/target/
|
||||||
src/main/resources/application-local.yml
|
src/main/resources/application-local.yml
|
||||||
|
jte-classes/
|
||||||
|
|
||||||
### STS ###
|
### STS ###
|
||||||
.apt_generated
|
.apt_generated
|
||||||
|
17
pom.xml
17
pom.xml
@ -34,6 +34,18 @@
|
|||||||
<groupId>org.springframework.boot</groupId>
|
<groupId>org.springframework.boot</groupId>
|
||||||
<artifactId>spring-boot-starter-web</artifactId>
|
<artifactId>spring-boot-starter-web</artifactId>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>gg.jte</groupId>
|
||||||
|
<artifactId>jte-spring-boot-starter-3</artifactId>
|
||||||
|
<version>3.1.12</version>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>gg.jte</groupId>
|
||||||
|
<artifactId>jte</artifactId>
|
||||||
|
<version>3.1.12</version>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.flywaydb</groupId>
|
<groupId>org.flywaydb</groupId>
|
||||||
<artifactId>flyway-core</artifactId>
|
<artifactId>flyway-core</artifactId>
|
||||||
@ -73,6 +85,11 @@
|
|||||||
<artifactId>spring-boot-testcontainers</artifactId>
|
<artifactId>spring-boot-testcontainers</artifactId>
|
||||||
<scope>test</scope>
|
<scope>test</scope>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework.security</groupId>
|
||||||
|
<artifactId>spring-security-test</artifactId>
|
||||||
|
<scope>test</scope>
|
||||||
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.testcontainers</groupId>
|
<groupId>org.testcontainers</groupId>
|
||||||
<artifactId>junit-jupiter</artifactId>
|
<artifactId>junit-jupiter</artifactId>
|
||||||
|
@ -25,6 +25,7 @@ import org.springframework.security.web.access.intercept.AuthorizationFilter;
|
|||||||
import org.springframework.security.web.authentication.LoginUrlAuthenticationEntryPoint;
|
import org.springframework.security.web.authentication.LoginUrlAuthenticationEntryPoint;
|
||||||
import org.springframework.security.web.authentication.SavedRequestAwareAuthenticationSuccessHandler;
|
import org.springframework.security.web.authentication.SavedRequestAwareAuthenticationSuccessHandler;
|
||||||
import org.springframework.security.web.authentication.preauth.j2ee.J2eePreAuthenticatedProcessingFilter;
|
import org.springframework.security.web.authentication.preauth.j2ee.J2eePreAuthenticatedProcessingFilter;
|
||||||
|
import se.su.dsv.oauth2.shibboleth.Entitlement;
|
||||||
import se.su.dsv.oauth2.shibboleth.ShibbolethAuthenticationDetailsSource;
|
import se.su.dsv.oauth2.shibboleth.ShibbolethAuthenticationDetailsSource;
|
||||||
|
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
@ -84,14 +85,18 @@ public class AuthorizationServer extends SpringBootServletInitializer {
|
|||||||
*/
|
*/
|
||||||
@Bean
|
@Bean
|
||||||
@Order(2)
|
@Order(2)
|
||||||
public SecurityFilterChain defaultSecurityFilterChain(HttpSecurity http)
|
public SecurityFilterChain defaultSecurityFilterChain(
|
||||||
|
HttpSecurity http,
|
||||||
|
Config config)
|
||||||
throws Exception
|
throws Exception
|
||||||
{
|
{
|
||||||
|
|
||||||
http.authorizeHttpRequests(authorize -> authorize
|
http.authorizeHttpRequests(authorize -> authorize
|
||||||
|
.requestMatchers("/admin/**").hasAuthority(Entitlement.asAuthority(config.adminEntitlement()))
|
||||||
.anyRequest().authenticated());
|
.anyRequest().authenticated());
|
||||||
|
|
||||||
http.exceptionHandling(exceptions -> exceptions
|
http.exceptionHandling(exceptions -> exceptions
|
||||||
|
.accessDeniedPage("/forbidden")
|
||||||
.authenticationEntryPoint(new LoginUrlAuthenticationEntryPoint("/login")));
|
.authenticationEntryPoint(new LoginUrlAuthenticationEntryPoint("/login")));
|
||||||
|
|
||||||
http.jee(jee -> jee
|
http.jee(jee -> jee
|
||||||
|
@ -5,6 +5,10 @@ import org.springframework.security.core.GrantedAuthority;
|
|||||||
public record Entitlement(String entitlement) implements GrantedAuthority {
|
public record Entitlement(String entitlement) implements GrantedAuthority {
|
||||||
@Override
|
@Override
|
||||||
public String getAuthority() {
|
public String getAuthority() {
|
||||||
|
return asAuthority(entitlement);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String asAuthority(String entitlement) {
|
||||||
return "ENTITLEMENT_" + entitlement;
|
return "ENTITLEMENT_" + entitlement;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
14
src/main/java/se/su/dsv/oauth2/web/AdminController.java
Normal file
14
src/main/java/se/su/dsv/oauth2/web/AdminController.java
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
package se.su.dsv.oauth2.web;
|
||||||
|
|
||||||
|
import org.springframework.stereotype.Controller;
|
||||||
|
import org.springframework.web.bind.annotation.GetMapping;
|
||||||
|
import org.springframework.web.bind.annotation.RequestMapping;
|
||||||
|
|
||||||
|
@Controller
|
||||||
|
@RequestMapping("/admin")
|
||||||
|
public class AdminController {
|
||||||
|
@GetMapping
|
||||||
|
public String index() {
|
||||||
|
return "admin/index";
|
||||||
|
}
|
||||||
|
}
|
12
src/main/java/se/su/dsv/oauth2/web/ErrorController.java
Normal file
12
src/main/java/se/su/dsv/oauth2/web/ErrorController.java
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
package se.su.dsv.oauth2.web;
|
||||||
|
|
||||||
|
import org.springframework.stereotype.Controller;
|
||||||
|
import org.springframework.web.bind.annotation.GetMapping;
|
||||||
|
|
||||||
|
@Controller
|
||||||
|
public class ErrorController {
|
||||||
|
@GetMapping("/forbidden")
|
||||||
|
public String forbidden() {
|
||||||
|
return "error/forbidden";
|
||||||
|
}
|
||||||
|
}
|
15
src/main/java/se/su/dsv/oauth2/web/PublicController.java
Normal file
15
src/main/java/se/su/dsv/oauth2/web/PublicController.java
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
package se.su.dsv.oauth2.web;
|
||||||
|
|
||||||
|
import org.springframework.security.core.Authentication;
|
||||||
|
import org.springframework.stereotype.Controller;
|
||||||
|
import org.springframework.ui.Model;
|
||||||
|
import org.springframework.web.bind.annotation.GetMapping;
|
||||||
|
|
||||||
|
@Controller
|
||||||
|
public class PublicController {
|
||||||
|
@GetMapping("/")
|
||||||
|
public String index(Model model, Authentication authentication) {
|
||||||
|
model.addAttribute("displayName", authentication.getName());
|
||||||
|
return "index";
|
||||||
|
}
|
||||||
|
}
|
@ -3,3 +3,7 @@ spring:
|
|||||||
name: dsv-oauth2-authorization-server
|
name: dsv-oauth2-authorization-server
|
||||||
profiles:
|
profiles:
|
||||||
include: local
|
include: local
|
||||||
|
gg:
|
||||||
|
jte:
|
||||||
|
templateLocation: src/main/resources/templates
|
||||||
|
developmentMode: true
|
||||||
|
1
src/main/resources/templates/admin/index.jte
Normal file
1
src/main/resources/templates/admin/index.jte
Normal file
@ -0,0 +1 @@
|
|||||||
|
admin/index.jte
|
1
src/main/resources/templates/error/forbidden.jte
Normal file
1
src/main/resources/templates/error/forbidden.jte
Normal file
@ -0,0 +1 @@
|
|||||||
|
Nuh uh
|
17
src/main/resources/templates/index.jte
Normal file
17
src/main/resources/templates/index.jte
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
@param String displayName
|
||||||
|
@param org.springframework.web.servlet.support.RequestContext springMacroRequestContext
|
||||||
|
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="en">
|
||||||
|
<head>
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||||
|
<title>DSV OAuth 2.0</title>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<main>
|
||||||
|
<h1>DSV OAuth 2.0</h1>
|
||||||
|
<p>Welcome ${displayName} to DSV's OAuth 2.0 information page</p>
|
||||||
|
<a href="${springMacroRequestContext.getContextUrl("/admin")}">Admin</a>
|
||||||
|
</main>
|
||||||
|
</body>
|
||||||
|
</html>
|
47
src/test/java/se/su/dsv/oauth2/web/AdminControllerTest.java
Normal file
47
src/test/java/se/su/dsv/oauth2/web/AdminControllerTest.java
Normal file
@ -0,0 +1,47 @@
|
|||||||
|
package se.su.dsv.oauth2.web;
|
||||||
|
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc;
|
||||||
|
import org.springframework.boot.test.context.SpringBootTest;
|
||||||
|
import org.springframework.boot.testcontainers.service.connection.ServiceConnection;
|
||||||
|
import org.springframework.test.web.servlet.MockMvc;
|
||||||
|
import org.testcontainers.containers.MariaDBContainer;
|
||||||
|
import org.testcontainers.junit.jupiter.Container;
|
||||||
|
import org.testcontainers.junit.jupiter.Testcontainers;
|
||||||
|
import se.su.dsv.oauth2.shibboleth.Entitlement;
|
||||||
|
|
||||||
|
import static org.springframework.security.test.web.servlet.request.SecurityMockMvcRequestPostProcessors.user;
|
||||||
|
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.*;
|
||||||
|
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.*;
|
||||||
|
|
||||||
|
@SpringBootTest(
|
||||||
|
properties = {
|
||||||
|
"se.su.dsv.oauth2.admin-entitlement=" + AdminControllerTest.ADMIN_ENTITLEMENT
|
||||||
|
}
|
||||||
|
)
|
||||||
|
@Testcontainers
|
||||||
|
@AutoConfigureMockMvc
|
||||||
|
class AdminControllerTest {
|
||||||
|
static final String ADMIN_ENTITLEMENT = "ADMIN";
|
||||||
|
|
||||||
|
@Container
|
||||||
|
@ServiceConnection
|
||||||
|
static MariaDBContainer<?> mariaDBContainer = new MariaDBContainer<>("mariadb:10.11");
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
MockMvc mockMvc;
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void is_protected() throws Exception {
|
||||||
|
mockMvc.perform(get("/admin"))
|
||||||
|
.andExpect(redirectedUrl("http://localhost/login"));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void is_accessible_with_admin_authority() throws Exception {
|
||||||
|
mockMvc.perform(get("/admin")
|
||||||
|
.with(user("admin").authorities(new Entitlement(ADMIN_ENTITLEMENT))))
|
||||||
|
.andExpect(status().isOk());
|
||||||
|
}
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user