Selaa lähdekoodia

6th labs: security, taglib, annotations

m_sudra 3 vuotta sitten
vanhempi
sitoutus
5fa1c364dc
20 muutettua tiedostoa jossa 422 lisäystä ja 54 poistoa
  1. 5 0
      wpfat_exercises/pom.xml
  2. 36 1
      wpfat_exercises/src/main/java/pl/sudra/configuration/SecurityConfiguration.java
  3. 33 0
      wpfat_exercises/src/main/java/pl/sudra/controller/AppUserRoleController.java
  4. 13 2
      wpfat_exercises/src/main/java/pl/sudra/controller/ExampleController.java
  5. 2 2
      wpfat_exercises/src/main/java/pl/sudra/controller/SpringSecurityCustomPagesController.java
  6. 53 2
      wpfat_exercises/src/main/java/pl/sudra/domain/AppUser.java
  7. 28 0
      wpfat_exercises/src/main/java/pl/sudra/domain/AppUserRole.java
  8. 1 0
      wpfat_exercises/src/main/java/pl/sudra/repository/AppUserRepository.java
  9. 12 0
      wpfat_exercises/src/main/java/pl/sudra/repository/AppUserRoleRepository.java
  10. 11 0
      wpfat_exercises/src/main/java/pl/sudra/service/AppUserRoleService.java
  11. 34 0
      wpfat_exercises/src/main/java/pl/sudra/service/AppUserRoleServiceImpl.java
  12. 7 1
      wpfat_exercises/src/main/java/pl/sudra/service/AppUserService.java
  13. 18 1
      wpfat_exercises/src/main/java/pl/sudra/service/AppUserServiceImpl.java
  14. 51 0
      wpfat_exercises/src/main/java/pl/sudra/service/MyAppUserDetailsService.java
  15. 50 35
      wpfat_exercises/src/main/webapp/appUser.jsp
  16. 32 0
      wpfat_exercises/src/main/webapp/appUserRole.jsp
  17. 19 9
      wpfat_exercises/src/main/webapp/hello.jsp
  18. 6 1
      wpfat_exercises/src/main/webapp/resources/i18n/messages_de.properties
  19. 5 0
      wpfat_exercises/src/main/webapp/resources/i18n/messages_en.properties
  20. 6 0
      wpfat_exercises/src/main/webapp/resources/i18n/messages_pl.properties

+ 5 - 0
wpfat_exercises/pom.xml

@@ -76,6 +76,11 @@
             <artifactId>spring-security-web</artifactId>
             <version>6.0.2</version>
         </dependency>
+        <dependency>
+            <groupId>org.springframework.security</groupId>
+            <artifactId>spring-security-taglibs</artifactId>
+            <version>6.0.2</version>
+        </dependency>
     </dependencies>
 
 </project>

+ 36 - 1
wpfat_exercises/src/main/java/pl/sudra/configuration/SecurityConfiguration.java

@@ -1,19 +1,48 @@
 package pl.sudra.configuration;
 
+import jakarta.annotation.Resource;
 import org.springframework.context.annotation.Bean;
 import org.springframework.context.annotation.Configuration;
+import org.springframework.security.authentication.dao.DaoAuthenticationProvider;
+import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
 import org.springframework.security.config.annotation.method.configuration.EnableMethodSecurity;
 import org.springframework.security.config.annotation.web.builders.HttpSecurity;
 import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
 import org.springframework.security.core.userdetails.User;
 import org.springframework.security.core.userdetails.UserDetails;
+import org.springframework.security.core.userdetails.UserDetailsService;
+import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
+import org.springframework.security.crypto.factory.PasswordEncoderFactories;
+import org.springframework.security.crypto.password.NoOpPasswordEncoder;
+import org.springframework.security.crypto.password.PasswordEncoder;
 import org.springframework.security.provisioning.InMemoryUserDetailsManager;
 import org.springframework.security.web.SecurityFilterChain;
+import org.springframework.security.web.csrf.CsrfFilter;
+import org.springframework.web.filter.CharacterEncodingFilter;
 
 @Configuration
 @EnableWebSecurity
-@EnableMethodSecurity
+@EnableGlobalMethodSecurity(prePostEnabled = true, securedEnabled = true)
 public class SecurityConfiguration {
+    @Resource(name = "myAppUserDetailsService")
+    private UserDetailsService userDetailsService;
+
+    @Bean
+    public PasswordEncoder passwordEncoder() {
+        return new BCryptPasswordEncoder();
+    }
+
+    @Bean
+    DaoAuthenticationProvider authProvider() {
+        DaoAuthenticationProvider authProvider = new DaoAuthenticationProvider();
+        // for database users
+        authProvider.setUserDetailsService(userDetailsService);
+        authProvider.setPasswordEncoder(passwordEncoder());
+        // for in-memory users
+        // authProvider.setUserDetailsService(userDetailsService());
+        return authProvider;
+    }
+
     @Bean
     public InMemoryUserDetailsManager userDetailsService() {
         UserDetails user = User.withDefaultPasswordEncoder()
@@ -36,9 +65,15 @@ public class SecurityConfiguration {
 
     @Bean
     public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
+        CharacterEncodingFilter filter = new CharacterEncodingFilter();
+        filter.setEncoding("UTF-8");
+        filter.setForceEncoding(true);
+        http.addFilterBefore(filter, CsrfFilter.class);
+
         http
                 .authorizeHttpRequests((authz) -> authz
                         .requestMatchers("/appUsers*").hasRole("ADMIN")
+                        .requestMatchers("/appUserRole*").hasRole("ADMIN")
                         .requestMatchers("/exampleOne").hasAuthority("ROLE_USER")
                         .requestMatchers("/exampleTwo").hasAnyAuthority("ROLE_STUDENT", "ROLE_ADMIN")
                         .requestMatchers("/exampleThree").hasRole("STUDENT")

+ 33 - 0
wpfat_exercises/src/main/java/pl/sudra/controller/AppUserRoleController.java

@@ -0,0 +1,33 @@
+package pl.sudra.controller;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Controller;
+import org.springframework.ui.Model;
+import org.springframework.validation.BindingResult;
+import org.springframework.web.bind.annotation.ModelAttribute;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestMethod;
+import pl.sudra.domain.AppUserRole;
+import pl.sudra.service.AppUserRoleService;
+
+@Controller
+public class AppUserRoleController {
+    private AppUserRoleService appUserRoleService;
+
+    @Autowired
+    public AppUserRoleController(AppUserRoleService appUserRoleService) {
+        this.appUserRoleService = appUserRoleService;
+    }
+
+    @RequestMapping(value = "/appUserRole")
+    public String showUserRole(Model model) {
+        model.addAttribute("appUserRole", new AppUserRole());
+        return "appUserRole";
+    }
+
+    @RequestMapping(value = "/addAppUserRole", method = RequestMethod.POST)
+    public String addUserRole(@ModelAttribute("appUserRole") AppUserRole appUserRole, BindingResult result) {
+        appUserRoleService.addAppUserRole(appUserRole);
+        return "redirect:appUsers.html";
+    }
+}

+ 13 - 2
wpfat_exercises/src/main/java/pl/sudra/controller/ExampleController.java

@@ -1,22 +1,33 @@
 package pl.sudra.controller;
 
+import org.springframework.security.authentication.AnonymousAuthenticationToken;
+import org.springframework.security.core.Authentication;
+import org.springframework.security.core.context.SecurityContextHolder;
 import org.springframework.stereotype.Controller;
 import org.springframework.web.bind.annotation.RequestMapping;
 
+import java.security.Principal;
+
 @Controller
 public class ExampleController {
     @RequestMapping(value = "/exampleOne")
-    public String exampleOne() {
+    public String exampleOne(Principal principal) {
+        System.out.println(principal.getName());
         return "exampleOne";
     }
 
     @RequestMapping(value = "/exampleTwo")
-    public String exampleTwo() {
+    public String exampleTwo(Authentication authentication) {
+        System.out.println(authentication.getName());
         return "exampleTwo";
     }
 
     @RequestMapping(value = "/exampleThree")
     public String exampleThree() {
+        Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
+        if (!(authentication instanceof AnonymousAuthenticationToken)) {
+            System.out.println(authentication.getName());
+        }
         return "exampleThree";
     }
 }

+ 2 - 2
wpfat_exercises/src/main/java/pl/sudra/controller/SpringSecurityCustomPagesController.java

@@ -12,10 +12,10 @@ public class SpringSecurityCustomPagesController {
                               @RequestParam(value = "login", required = false) String logout,
                               Model model) {
         if (error != null) {
-            model.addAttribute("error", "Invalid usernameand password!");
+            model.addAttribute("error", "Invalid username and password!");
         }
         if (logout != null) {
-            model.addAttribute("msg", "You've been logged out succesfully.");
+            model.addAttribute("msg", "You've been logged out successfully.");
         }
         return "login";
     }

+ 53 - 2
wpfat_exercises/src/main/java/pl/sudra/domain/AppUser.java

@@ -4,25 +4,44 @@ import jakarta.persistence.*;
 import jakarta.validation.constraints.NotNull;
 import jakarta.validation.constraints.Size;
 
+import java.util.HashSet;
+import java.util.Set;
+
 @Entity
-@Table(name = "appUser")
+@Table(name = "appuser")
 public class AppUser {
 
     @Id
     @GeneratedValue(strategy = GenerationType.IDENTITY)
     long id;
+
     @NotNull
     @Column(name = "firstName", nullable = false)
     @Size(min = 2, max = 30, message = "{error.size.firstName}")
     private String firstName;
+
     @NotNull
     @Size(min = 2, max = 30)
     private String lastName;
+
     @NotNull
     private String email;
+
     @Size(min = 9, max = 9)
     private String telephone;
 
+    @NotNull
+    @Column(unique = true)
+    private String login;
+
+    @NotNull
+    private String password;
+
+    private boolean enabled;
+
+    @ManyToMany(fetch = FetchType.EAGER)
+    private Set<AppUserRole> appUserRole = new HashSet<AppUserRole>(0);
+
     public long getId() {
         return id;
     }
@@ -62,4 +81,36 @@ public class AppUser {
     public void setTelephone(String telephone) {
         this.telephone = telephone;
     }
-}
+
+    public String getLogin() {
+        return login;
+    }
+
+    public void setLogin(String login) {
+        this.login = login;
+    }
+
+    public String getPassword() {
+        return password;
+    }
+
+    public void setPassword(String password) {
+        this.password = password;
+    }
+
+    public boolean isEnabled() {
+        return enabled;
+    }
+
+    public void setEnabled(boolean enabled) {
+        this.enabled = enabled;
+    }
+
+    public Set<AppUserRole> getAppUserRole() {
+        return appUserRole;
+    }
+
+    public void setAppUserRole(Set<AppUserRole> appUserRole) {
+        this.appUserRole = appUserRole;
+    }
+}

+ 28 - 0
wpfat_exercises/src/main/java/pl/sudra/domain/AppUserRole.java

@@ -0,0 +1,28 @@
+package pl.sudra.domain;
+
+import jakarta.persistence.*;
+
+@Entity
+@Table(name="appuserrole")
+public class AppUserRole {
+    @Id
+    @GeneratedValue(strategy = GenerationType.AUTO)
+    private Long id;
+    private String role;
+
+    public Long getId() {
+        return id;
+    }
+
+    public void setId(Long id) {
+        this.id = id;
+    }
+
+    public String getRole() {
+        return role;
+    }
+
+    public void setRole(String role) {
+        this.role = role;
+    }
+}

+ 1 - 0
wpfat_exercises/src/main/java/pl/sudra/repository/AppUserRepository.java

@@ -14,6 +14,7 @@ public interface AppUserRepository extends JpaRepository<AppUser, Long> {
     List<AppUser> findByLastName(String lastName);
 
     AppUser findById(long id);
+    AppUser findByLogin(String Login);
 
 }
 

+ 12 - 0
wpfat_exercises/src/main/java/pl/sudra/repository/AppUserRoleRepository.java

@@ -0,0 +1,12 @@
+package pl.sudra.repository;
+
+import jakarta.transaction.Transactional;
+import org.springframework.data.jpa.repository.JpaRepository;
+import org.springframework.stereotype.Repository;
+import pl.sudra.domain.AppUserRole;
+
+@Transactional
+@Repository
+public interface AppUserRoleRepository extends JpaRepository<AppUserRole, Long> {
+    AppUserRole findByRole(String role);
+}

+ 11 - 0
wpfat_exercises/src/main/java/pl/sudra/service/AppUserRoleService.java

@@ -0,0 +1,11 @@
+package pl.sudra.service;
+
+import pl.sudra.domain.AppUserRole;
+
+import java.util.List;
+
+public interface AppUserRoleService {
+    void addAppUserRole(AppUserRole appUserRole);
+    List<AppUserRole> listAppUserRole();
+    AppUserRole getAppUserRole(long id);
+}

+ 34 - 0
wpfat_exercises/src/main/java/pl/sudra/service/AppUserRoleServiceImpl.java

@@ -0,0 +1,34 @@
+package pl.sudra.service;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+import pl.sudra.domain.AppUserRole;
+import pl.sudra.repository.AppUserRoleRepository;
+
+import java.util.List;
+
+@Service("appUserRoleService")
+public class AppUserRoleServiceImpl implements AppUserRoleService {
+    private AppUserRoleRepository appUserRoleRepository;
+
+    @Autowired
+    public AppUserRoleServiceImpl(AppUserRoleRepository appUserRoleRepository) {
+        this.appUserRoleRepository = appUserRoleRepository;
+    }
+
+    @Transactional
+    public void addAppUserRole(AppUserRole appUserRole) {
+        appUserRoleRepository.save(appUserRole);
+    }
+
+    @Transactional
+    public List<AppUserRole> listAppUserRole() {
+        return appUserRoleRepository.findAll();
+    }
+
+    @Transactional
+    public AppUserRole getAppUserRole(long id) {
+        return appUserRoleRepository.getOne(id);
+    }
+}

+ 7 - 1
wpfat_exercises/src/main/java/pl/sudra/service/AppUserService.java

@@ -1,19 +1,25 @@
 package pl.sudra.service;
 
+import org.springframework.security.access.annotation.Secured;
+import org.springframework.security.access.prepost.PreAuthorize;
 import pl.sudra.domain.AppUser;
 
 import java.util.List;
 
 public interface AppUserService {
-
+    @Secured("ROLE_ADMIN")
     void addAppUser(AppUser appUser);
 
+    @PreAuthorize("hasRole('ROLE_ADMIN') OR (#appUser.login == principal.username)")
     void editAppUser(AppUser appUser);
 
     List<AppUser> listAppUser();
 
+    @Secured("ROLE_ADMIN")
     void removeAppUser(long id);
 
     AppUser getAppUser(long id);
 
+    AppUser findByLogin(String login);
+
 }

+ 18 - 1
wpfat_exercises/src/main/java/pl/sudra/service/AppUserServiceImpl.java

@@ -1,10 +1,12 @@
 package pl.sudra.service;
 
 import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.security.crypto.password.PasswordEncoder;
 import org.springframework.stereotype.Service;
 import org.springframework.transaction.annotation.Transactional;
 import pl.sudra.domain.AppUser;
 import pl.sudra.repository.AppUserRepository;
+import pl.sudra.repository.AppUserRoleRepository;
 
 import java.util.List;
 
@@ -12,19 +14,29 @@ import java.util.List;
 public class AppUserServiceImpl implements AppUserService {
 
     private AppUserRepository appUserRepository;
+    private AppUserRoleRepository appUserRoleRepository;
+    private PasswordEncoder passwordEncoder;
 
     @Autowired
-    public AppUserServiceImpl(AppUserRepository appUserRepository) {
+    public AppUserServiceImpl(AppUserRepository appUserRepository,
+                              AppUserRoleRepository appUserRoleRepository,
+                              PasswordEncoder passwordEncoder) {
         this.appUserRepository = appUserRepository;
+        this.appUserRoleRepository = appUserRoleRepository;
+        this.passwordEncoder = passwordEncoder;
     }
 
     @Transactional
     public void addAppUser(AppUser appUser) {
+        appUser.getAppUserRole().add(appUserRoleRepository.findByRole("ROLE_USER"));
+        appUser.setPassword(passwordEncoder.encode(appUser.getPassword()));
         appUserRepository.save(appUser);
     }
 
     @Transactional
     public void editAppUser(AppUser appUser) {
+        appUser.getAppUserRole().add(appUserRoleRepository.findByRole("ROLE_USER"));
+        appUser.setPassword(passwordEncoder.encode(appUser.getPassword()));
         appUserRepository.save(appUser);
     }
 
@@ -42,6 +54,11 @@ public class AppUserServiceImpl implements AppUserService {
     public AppUser getAppUser(long id) {
         return appUserRepository.findById(id);
     }
+
+    @Transactional
+    public AppUser findByLogin(String login) {
+        return appUserRepository.findByLogin(login);
+    }
 }
 
 

+ 51 - 0
wpfat_exercises/src/main/java/pl/sudra/service/MyAppUserDetailsService.java

@@ -0,0 +1,51 @@
+package pl.sudra.service;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.security.core.GrantedAuthority;
+import org.springframework.security.core.authority.SimpleGrantedAuthority;
+import org.springframework.security.core.userdetails.User;
+import org.springframework.security.core.userdetails.UserDetails;
+import org.springframework.security.core.userdetails.UserDetailsService;
+import org.springframework.security.core.userdetails.UsernameNotFoundException;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+import pl.sudra.domain.AppUserRole;
+
+import java.util.ArrayList;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+
+@Service("myAppUserDetailsService")
+public class MyAppUserDetailsService implements UserDetailsService {
+    private AppUserService appUserService;
+
+    @Autowired
+    public MyAppUserDetailsService(AppUserService appUserService) {
+        this.appUserService = appUserService;
+    }
+
+    @Transactional(readOnly = true)
+    @Override
+    public UserDetails loadUserByUsername(final String login) throws UsernameNotFoundException {
+        pl.sudra.domain.AppUser appUser = appUserService.findByLogin(login);
+        List<GrantedAuthority> authorities = buildUserAuthority(appUser.getAppUserRole());
+        return buildUserForAuthentication(appUser, authorities);
+    }
+
+    // Converts AppUser to org.springframework.security.core.userdetails.User
+    private User buildUserForAuthentication(pl.sudra.domain.AppUser appUser, List<GrantedAuthority> authorities) {
+        return new User(appUser.getLogin(), appUser.getPassword(), appUser.isEnabled(),
+                true, true, true, authorities);
+    }
+
+    private List<GrantedAuthority> buildUserAuthority(Set<AppUserRole> appUserRoles) {
+        Set<GrantedAuthority> setAuths = new HashSet<>();
+        // Build user's authorities
+        for (AppUserRole appUserRole : appUserRoles) {
+            setAuths.add(new SimpleGrantedAuthority(appUserRole.getRole()));
+        }
+        List<GrantedAuthority> result = new ArrayList<>(setAuths);
+        return result;
+    }
+}

+ 50 - 35
wpfat_exercises/src/main/webapp/appUser.jsp

@@ -17,41 +17,56 @@
 
 <h1>App user info:</h1>
 <form:form method="post" action="addAppUser" modelAttribute="appUser">
-<table>
-    <tr>
-        <td><form:hidden path="id"/>
-    </tr>
-    <tr>
-        <td><form:label path="firstName"><spring:message code="label.firstName"/></form:label></td>
-        <td><form:input path="firstName"/></td>
-        <td><form:errors path="firstName"/></td>
-    </tr>
-    <tr>
-        <td><form:label path="lastName"><spring:message code="label.lastName"/></form:label></td>
-        <td><form:input path="lastName"/></td>
-        <td><form:errors path="lastName"/></td>
-    </tr>
-    <tr>
-        <td><form:label path="email"><spring:message code="label.email"/></form:label></td>
-        <td><form:input path="email"/></td>
-        <td><form:errors path="email"/></td>
-    </tr>
-    <tr>
-        <td><form:label path="telephone"><spring:message code="label.telephone"/></form:label></td>
-        <td><form:input path="telephone"/></td>
-        <td><form:errors path="telephone"/></td>
-    </tr>
-    <tr>
-        <td colspan="2">
-            <c:if test="${appUser.id==0}">
-                <input type="submit" value="<spring:message code="label.addAppUser"/>"/>
-            </c:if>
-            <c:if test="${appUser.id!=0}">
-                <input type="submit" value="<spring:message code="label.editAppUser"/>"/>
-            </c:if>
-        </td>
-    </tr>
-</table>
+    <table>
+        <tr>
+            <td><form:hidden path="id"/>
+        </tr>
+        <tr>
+            <td><form:label path="login"><spring:message code="label.login"/></form:label></td>
+            <td><form:input path="login"/></td>
+            <td><form:errors path="login"/></td>
+        </tr>
+        <tr>
+            <td><form:label path="password"><spring:message code="label.password"/></form:label></td>
+            <td><form:input path="password"/></td>
+            <td><form:errors path="password"/></td>
+        </tr>
+        <tr>
+            <td><form:label path="enabled"><spring:message code="label.enabled"/></form:label></td>
+            <td><form:checkbox path="enabled"/></td>
+            <td><form:errors path="enabled"/></td>
+        </tr>
+        <tr>
+            <td><form:label path="firstName"><spring:message code="label.firstName"/></form:label></td>
+            <td><form:input path="firstName"/></td>
+            <td><form:errors path="firstName"/></td>
+        </tr>
+        <tr>
+            <td><form:label path="lastName"><spring:message code="label.lastName"/></form:label></td>
+            <td><form:input path="lastName"/></td>
+            <td><form:errors path="lastName"/></td>
+        </tr>
+        <tr>
+            <td><form:label path="email"><spring:message code="label.email"/></form:label></td>
+            <td><form:input path="email"/></td>
+            <td><form:errors path="email"/></td>
+        </tr>
+        <tr>
+            <td><form:label path="telephone"><spring:message code="label.telephone"/></form:label></td>
+            <td><form:input path="telephone"/></td>
+            <td><form:errors path="telephone"/></td>
+        </tr>
+        <tr>
+            <td colspan="2">
+                <c:if test="${appUser.id==0}">
+                    <input type="submit" value="<spring:message code="label.addAppUser"/>"/>
+                </c:if>
+                <c:if test="${appUser.id!=0}">
+                    <input type="submit" value="<spring:message code="label.editAppUser"/>"/>
+                </c:if>
+            </td>
+        </tr>
+    </table>
 </form:form>
 
 <h3><spring:message code="label.userList"/></h3>

+ 32 - 0
wpfat_exercises/src/main/webapp/appUserRole.jsp

@@ -0,0 +1,32 @@
+<%@ taglib prefix="form" uri="http://www.springframework.org/tags/form" %>
+<%@ taglib uri="http://www.springframework.org/tags" prefix="spring" %>
+<%@ page contentType="text/html;charset=UTF-8" language="java" %>
+<html>
+<head>
+    <title>AppUserRole</title>
+</head>
+<body>
+<form:form method="post" action="addAppUserRole" modelAttribute="appUserRole">
+    <table>
+        <tr>
+            <td><form:hidden path="id"/></td>
+        </tr>
+        <tr>
+            <td>
+                <form:label path="role">
+                    <spring:message code="label.role"/>
+                </form:label>
+            </td>
+            <td><form:input path="role"/></td>
+            <td><form:errors path="role"/></td>
+        </tr>
+        <tr>
+            <td colspan="2">
+                <input type="submit" value="<spring:message code="label.addAppUserRole"/>"/>
+            </td>
+        </tr>
+    </table>
+</form:form>
+
+</body>
+</html>

+ 19 - 9
wpfat_exercises/src/main/webapp/hello.jsp

@@ -1,4 +1,5 @@
 <%@ taglib prefix="spring" uri="http://www.springframework.org/tags" %>
+<%@ taglib prefix="sec" uri="http://www.springframework.org/security/tags" %>
 <%@ page contentType="text/html;charset-UTF-@" %>
 <html>
 <head>
@@ -7,17 +8,26 @@
 <body>
 <h3>Hello World!</h3>
 
-<a href="${pageContext.request.contextPath}/appUsers">App Users page</a>
-<br/>
+<sec:authorize access="isAnonymous()">
+    <a href="/login.html"><spring:message code="label.login"/></a><br/>
+</sec:authorize>
 
-<br/>
-<a href="/exampleOne"><spring:message code="label.example"/> 1</a>
-<br/>
-<a href="/exampleTwo"><spring:message code="label.example"/> 2</a>
-<br/>
-<a href="/exampleThree"><spring:message code="label.example"/> 3</a>
-<br/>
+<sec:authorize access="hasRole('ROLE_ADMIN')">
+    <a href="/appUsers"><spring:message code="label.addAppUser"/></a><br/>
+    <a href="/appUserRole"><spring:message code="label.role"/></a><br/>
+</sec:authorize>
+
+<sec:authorize access="hasRole('ROLE_USER')">
+    <a href="/exampleOne"><spring:message code="label.example"/> 1</a><br/>
+</sec:authorize>
+
+<sec:authorize access="hasAnyRole('ROLE_STUDENT','ROLE_ADMIN')">
+    <a href="/exampleTwo"><spring:message code="label.example"/> 2</a><br/>
+</sec:authorize>
 
+<sec:authorize access="hasRole('ROLE_STUDENT')">
+    <a href="/exampleThree"><spring:message code="label.example"/> 3</a><br/>
+</sec:authorize>
 <br/>
 ${serverTime}
 

+ 6 - 1
wpfat_exercises/src/main/webapp/resources/i18n/messages_de.properties

@@ -13,4 +13,9 @@ error.size.firstName=   Die Großße muss zwischen {min} und {max} liegen.
 label.welcome       =   Willkomen
 label.example       =   Beispiel
 
-label.accessDenied  =   Zugriff verweigert
+label.accessDenied  =   Zugriff verweigert
+label.login         =   Login
+label.password      =   Passwort
+label.enabled       =   Aktiv
+label.role          =   Benutzerrolle
+label.addAppUserRole=   Benutzerrolle hinzuf&#252;gen

+ 5 - 0
wpfat_exercises/src/main/webapp/resources/i18n/messages_en.properties

@@ -14,3 +14,8 @@ label.welcome       =   Welcome
 label.example       =   Example
 
 label.accessDenied  =   Access denied
+label.login         =   Login
+label.password      =   Password
+label.enabled       =   Active
+label.role          =   Role
+label.addAppUserRole=   Add user role

+ 6 - 0
wpfat_exercises/src/main/webapp/resources/i18n/messages_pl.properties

@@ -14,3 +14,9 @@ label.welcome       =   Witaj
 label.example       =   Przykład
 
 label.accessDenied  =   Odmowa dostępu
+label.login         =   Login
+label.password      =   Hasło
+label.enabled       =   Aktywny
+label.role          =   Rola
+label.addAppUserRole=   Dodaj rolę użytkownika
+