I have a simple java application where I would like all my pages to have access to the style sheet folder and files even if the user has not been authenticated. I have the following code in my WebSecurityConfig.java file:
package com.security;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.builders.WebSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
// Add WebSecurityConfig class to configure security
#Configuration
#EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
private static final String USER = "USER";
#Override
protected void configure(HttpSecurity http) throws Exception {
http
.authorizeRequests()
.antMatchers("/", "/security").permitAll()
.antMatchers("/css/**.css").permitAll()
.antMatchers("/hands_on").hasAnyRole(USER)
.anyRequest().authenticated()
.and()
.formLogin()
.loginPage("/login")
.permitAll()
.and()
.logout()
.permitAll();
}
#Autowired
public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
auth
.inMemoryAuthentication()
.withUser("user").password("password").roles("USER");
}
}
I have this code in my hands_on.html file:
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:th="http://www.thymeleaf.org"
xmlns:sec="http://www.thymeleaf.org/thymeleaf-extras-springsecurity3">
<head>
<title>hands on Demo</title>
<link th:href="#{/css/style.css}" rel="stylesheet" type="text/css" />
</head>
<body>
<h1>hands on Demo</h1>
</body>
</html>
And I have this code in my login.html file:
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:th="http://www.thymeleaf.org"
xmlns:sec="http://www.thymeleaf.org/thymeleaf-extras-springsecurity3">
<head>
<title>Spring Security Demo</title>
<link th:href="#{/css/style.css}" rel="stylesheet" type="text/css" />
</head>
<body>
<div th:if="${param.error}">
Invalid username and password.
</div>
<div th:if="${param.logout}">
You have been logged out.
</div>
<form th:action="#{/login}" method="post">
<div><label> Enter your User Name : <input type="text" name="username"/> </label></div>
<div><label> Enter your Password: <input type="password" name="password"/> </label></div>
<div><input type="submit" value="Sign In"/></div>
</form>
</body>
</html>
If I start my java application and launch a browser and go to localhost:8080/hands_on I would expect the login page to get displayed and be presented with my style sheet. What happens is the login page gets displayed but without the styles being applied. When I look at my javascript console, I see this:
Refused to apply style from 'http://localhost:8080/css/style.css' because its MIME type ('application/json') is not a supported stylesheet MIME type, and strict MIME checking is enabled.
My style.css file is in the folder security[boot]/src/main/resources/static/css.
I thought I would have access to the style.css file based on the .antMatchers("/css/**.css").permitAll() in my WebSecurityConfig.java file but I guess I am missing something. Ideas?
Related
This question is a continuation of this one but now with some changes that I was hoping to solve the initial problem. I have created a Spring Boot app that currently runs on HTTPS. For that matter I used this Youtube guide.
PROBLEM
I can't find a way to redirect from my HTTPS Spring Boot app to URLs on external HTTPS server. I am fetching those URLs from external API through POJO class, store them in PostgreSQL and expose them through Thymeleaf on HTML page. If, for example, my initial URL is
`https://www.investing.com/news/cryptocurrency-news/tether-liquidates-celsius-position-with-no-losses-to-stablecoin-issuer-2845626`
gets chopped off to
https://www.investing.com/
Is it possible while my controller method being invoked as GET request, to simutaneously implement an auto-POST request in order to grab the URLs, have another controller with #RequestBody that deserializes them, returns them as String Values, and returns a redirection to them? In the initial question I made, I used a GET controller with #RequestParam anootation, but I am getting null values.
Controller Method
//Method to handle the HTTP request for showing DB contents
#GetMapping("/show-newscontents")
public String showAllRates(HttpServletRequest request){
request.setAttribute("rates", newsService.showAllRates());
return "newsdbcontents";
}
HMTL Thymeleaf
<!DOCTYPE HTML>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<title>Spring Boot Thymeleaf Hello World Example</title>
<link rel="stylesheet" th:href="#{/webjars/bootstrap/css/bootstrap.min.css}"/>
<link rel="stylesheet" th:href="#{/styles/db.css}"/>
<script type="text/javascript" th:src="#{/webjars/bootstrap/js/bootstrap.min.js}"></script>
</head>
<body>
<ul>
<li>Home</li>
<li>Movies Contents</li>
<li>Github</li>
</ul>
<main role="main" class="container">
<div class="starter-template">
<h1>Cryptocurrency News</h1>
</div>
</main>
<!--Display DB contents on HTML and Thymeleaf-->
<div class="container text-center" id="tasksDiv">
<hr>
<div class="table-responsive">
<table class="table table-striped table-bordered">
<thead>
<tr>
<th>Related Image</th>
<th>News Provider Name</th>
<th>News Link</th>
</tr>
</thead>
<tbody>
<tr th:each="rate: ${rates}">
<td> <img th:src="${rate.related_image}" alt="error displaying image"> </td>
<td th:text="${rate.news_provider_name}"> </td>
<td>
<a
href="#"
th:href="#{${rate.news_link}}"
th:text="${rate.HEADLINE}">
</a>
</td>
</tr>
</tbody>
</table>
</div>
</div>
</body>
</html>
Since I am involving security issues here, I think it is appropiate to mention that I've implemented Spring Security with some simple Basic Auth, as follows.
Security Configuration Class
package com.andrekreou.iot.security;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.web.SecurityFilterChain;
//WebSecurityConfigurerAdapter has been deprecated
#Configuration
public class ApplicationSecurityConfig {
#Bean
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
http
.authorizeRequests()
.anyRequest()
.authenticated()
.and()
.httpBasic();
return http.build();
}
}
Finally I am providing my application.properties file code
Application Properties
spring.datasource.url=jdbc:postgresql://localhost:5432/iot
spring.datasource.username=
spring.datasource.password=
spring.datasource.driver-class-name=org.postgresql.Driver
spring.jpa.hibernate.ddl-auto=create
spring.jpa.show-sql=true
spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.PostgreSQLDialect
spring.jpa.properties.hibernate.format_sql=true
#Server properties for HTTPS configuration
server.ssl.enabled=true
server.ssl.key-store-type=PKCS12
server.ssl.key-store=classpath:local-ssl.p12
server.ssl.key-store-password=
server.ssl.key-password=
server.servlet.context-path=/
server.ssl.key-alias=local_ssl
server.port=8443
#This message will be injected in Welcome MoviesController
welcome.message= User
spring.thymeleaf.prefix=classpath:/templates/
spring.thymeleaf.suffix=.html
spring.thymeleaf.cache=false
server.error.include-message=always
I am facing quite an interesting issue. In my controller class I added path #RequestMapping("/product"). Inside class when I put a path on method like #GetMapping("/update/{productId}") that means when I divided path by / I cannot access asset file in my html page. But if I define path like #GetMapping("/{productId}") it works fine. Using path like #GetMapping("/update/{productId}") this my asset URL become like this.
http://localhost:8080/product/assets/js/editor/ckeditor/ckeditor.custom.js
You can see /product/ added automatically in the URL. As a result, html page cannot find those assets as there is no product folder and get 404
And using a path like #GetMapping("/{productId}") asset url become fine
http://localhost:8080/assets/js/editor/ckeditor/ckeditor.custom.js
My controller class is
#Controller
#RequestMapping("/product")
public class AdminProductController {
#GetMapping("/update/{productId}")
ModelAndView modelAndView = new ModelAndView("admin/add-product");
//my code
return modelAndView;
}
}
In my WebSecurityConfig i configured like bellow.
#Override
protected void configure(HttpSecurity http) throws Exception {
http
.csrf().disable()
.authorizeRequests()
.antMatchers("/", "/admin/login","/customer/login", "/logout","/file/**").permitAll()
.antMatchers("/admin/**","/category/**","/product/*").hasAnyAuthority("ROLE_ADMIN")
.antMatchers("/customer/**").hasAnyAuthority("ROLE_CUSTOMER")
.anyRequest().authenticated()
.and()
.formLogin()
.loginPage("/admin/login")
.loginProcessingUrl("/login")
.loginPage("/customer/login")
.loginProcessingUrl("/login")
.failureUrl("/customer/login?error")
.successHandler(successHandler);
http
.logout()
.logoutUrl("/logout")
.logoutSuccessUrl("/")
.deleteCookies("JSESSIONID")
.invalidateHttpSession(true)
.permitAll();
}
#Override
public void configure(WebSecurity web) throws Exception {
web
.ignoring()
.antMatchers("/resources/**", "/static/**", "/assets/**", "/css/**", "/fonts/**", "/js/**", "/images/**");
}
and I also added this code in WbMvcConfifure
#Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
registry.addResourceHandler("/resources/static/**").addResourceLocations("classpath:META-INF/resources/static/");
}
and here is my add-product.html
<!DOCTYPE html>
<html lang="en" xmlns="http://www.w3.org/1999/xhtml"
xmlns:th="http://www.thymeleaf.org">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta name="description"
content="Bigdeal admin is super flexible, powerful, clean & modern responsive bootstrap 4 admin template with unlimited possibilities.">
<meta name="keywords"
content="admin template, Bigdeal admin template, dashboard template, flat admin template, responsive admin template, web app">
<meta name="author" content="pixelstrap">
<link rel="icon" href="../assets/images/favicon/favicon.ico"
type="image/x-icon">
<link rel="shortcut icon" href="../assets/images/favicon/favicon.ico"
type="image/x-icon">
<title>P&S Craft- Hand made,Hand print & Natural</title>
<!-- Google font-->
<link
href="https://fonts.googleapis.com/css?family=Work+Sans:100,200,300,400,500,600,700,800,900"
rel="stylesheet">
<link
href="https://fonts.googleapis.com/css?family=Nunito:200,200i,300,300i,400,400i,600,600i,700,700i,800,800i,900,900i"
rel="stylesheet">
<!-- Font Awesome-->
<link rel="stylesheet" type="text/css"
th:href="#{/assets/css/font-awesome.css}">
<!-- Flag icon-->
<link rel="stylesheet" type="text/css"
href="#{/assets/css/flag-icon.css}">
<!-- Bootstrap css-->
<link rel="stylesheet" type="text/css"
th:href="#{/assets/css/bootstrap.css}">
<!-- App css-->
<link rel="stylesheet" type="text/css" th:href="#{/assets/css/admin.css}">
<link rel="stylesheet"
href="https://cdnjs.cloudflare.com/ajax/libs/Dropify/0.2.2/css/dropify.min.css" />
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/dropzone/5.5.1/dropzone.css" />
</head>
<body>
<!-- page-wrapper Start-->
<div class="page-wrapper">
<!-- Page Header Start-->
<div th:replace="fragments/header_admin :: header"></div>
<!-- Page Header Ends -->
<!-- Page Body Start-->
<div class="page-body-wrapper">
<!-- Page Sidebar Start-->
<div th:replace="fragments/leftsidebar_admin :: leftsidebar"></div>
<!-- Page Sidebar Ends-->
<!-- Right sidebar Start-->
<div th:replace="fragments/rightsidebar_admin :: rightsidebar"></div>
<!-- Right sidebar Ends-->
<div class="page-body">
<!-- Container-fluid starts-->
<div class="container-fluid">
<div class="page-header">
<div class="row">
<div class="col-lg-6">
<div class="page-header-left">
<h3>
Add Products
</h3>
</div>
</div>
</div>
</div>
</div>
<!-- Container-fluid Ends-->
<!-- Container-fluid starts-->
<div class="container-fluid">
</div>
<!-- Container-fluid Ends-->
</div>
<!-- footer start-->
<div th:replace="fragments/footer_admin :: footer"></div>
<!-- footer end-->
</div>
</div>
<!-- latest jquery-->
<script src="../assets/js/jquery-3.3.1.min.js"></script>
<!-- Bootstrap js-->
<script src="../assets/js/popper.min.js"></script>
<script src="../assets/js/bootstrap.js"></script>
<!-- feather icon js-->
<script src="../assets/js/icons/feather-icon/feather.min.js"></script>
<script src="../assets/js/icons/feather-icon/feather-icon.js"></script>
<!-- Sidebar jquery-->
<script src="../assets/js/sidebar-menu.js"></script>
<!-- touchspin js-->
<script src="../assets/js/touchspin/vendors.min.js"></script>
<script src="../assets/js/touchspin/touchspin.js"></script>
<script src="../assets/js/touchspin/input-groups.min.js"></script>
<!-- form validation js-->
<script src="../assets/js/dashboard/form-validation-custom.js"></script>
<!-- ckeditor js-->
<script src="../assets/js/editor/ckeditor/ckeditor.js"></script>
<script src="../assets/js/editor/ckeditor/styles.js"></script>
<script src="../assets/js/editor/ckeditor/adapters/jquery.js"></script>
<script src="../assets/js/editor/ckeditor/ckeditor.custom.js"></script>
<!-- Zoom js-->
<script src="../assets/js/jquery.elevatezoom.js"></script>
<script src="../assets/js/zoom-scripts.js"></script>
<!--Customizer admin-->
<script src="../assets/js/admin-customizer.js"></script>
<!-- lazyload js-->
<script src="../assets/js/lazysizes.min.js"></script>
<!--right sidebar js-->
<script src="../assets/js/chat-menu.js"></script>
<!--script admin-->
<script src="../assets/js/admin-script.js"></script>
</body>
</html>
and here is my folder structure
Any suggestions will be appreciated!
All the assets have to be linked using the approach:
th:href="#{/assets/css/<your css file name here>}"
Same with JS and any other static resources placed under src/main/resources/static
I'm currently working on a Docker-deployed Spring application with an nginx-reverse proxy and want to access a subdomain via #GetMapping & #PostMapping.
What is the correct way to access e.g. the /entity/add subdomain?
Is this a code error or might my server be malconfigured? Is there anything else needed in order to correctly review this problem? I'll gladly add it.
I've looked up the official documentation, guides, other StackOverflow posts etc., but none of them seem to work.
Controller.java:
public class EntityController {
private Repository repository;
#ModelAttribute("entity")
public Entity newEntity() {
return new Entity();
}
// Overview.
#GetMapping("/entity")
public String index(Model model) {
final Iterable<Entity> all = repository.findAll();
model.addAttribute("all", all);
return "index";
}
// New entity.
#GetMapping("/entity/add")
public String loadAddPage(Model model) {
model.addAttribute("entity", new Entity());
return "add";
}
#PostMapping("/entity/add")
public String submitEntity(#Valid #ModelAttribute Entity entity, BindingResult bindingResult) {
if (bindingResult.hasErrors()) {
return "add";
}
repository.save(entity);
return "redirect:/index";
}
index.html:
<!DOCTYPE html>
<html lang="en" xmlns="http://www.w3.org/1999/xhtml" xmlns:th="http://www.thymeleaf.org">
<head>
<title>Overview</title>
<meta charset="UTF-8" />
</head>
<body>
<div class="container">
<h2>Entities</h2>
<form action="/entity/add" method="get">
<input type="submit" value="New Entity"/>
</form>
<div class="content" th:each="entity: ${all}">
<h2 th:text="${entity.name}">Name</h2>
<form th:href="#{/entity/details?id={entityId}(entityId=${entity.id})}">
<input type="submit" value="Edit"/>
</form>
<!--<button><a th:href="#{/entity/update?entityId={entityId}(entityId=${entity.id})}"></a></button>-->
</div>
</div>
</body>
</html>
add.hmtl:
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
<title>New entity</title>
<meta http-equiv="Content-Type" content="text/html" charset="UTF-8" />
</head>
<body>
<div class="container">
<form action="/entity/add" method="post" th:object="${entity}">
<table>
<tr>
<td><label for="name">Name</label></td>
<td><input id="name" type="text" th:text="Name" th:field="*{name}" /></td>
</tr>
</table>
</form>
</div>
</body>
</html>
I expect that a click on the /entity/add-form in index.html correctly links me to entity/add, but it just displays a 404 error. Same with other tested subdomains.
Edit 01: Title updated. (access subdomains -> access URLs)
I understand your question as you need to submit the form to this action url "/entity/add" with method POST. Consider using the Thymeleaf view templates for rendering the server side actions. Check with the following
Change the HTML action attribute to th:action attribute.
Provide the Submit action button to submit the form.
Check this url for more information: https://spring.io/guides/gs/handling-form-submission/
Disclaimer: This is my comment for your question. As I don't have the reputation, I am posting as answer.
I suppose you are using thymeleaf for templating.
Add following in application.properties file:
spring.application.name: my-app-context-path
In Controller :
#GetMapping({"/", "/index"})
public String defaultPage(final Model model, final Locale locale) throws MyException {
addGameInfo(model);
return "index";
}
#GetMapping({"/match/{gameId}"}){
--------
------
}
In view:
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:th="http://www.thymeleaf.org">
....
....
<h1 class="text-primary">Featured Games</h1><a class="btn btn-flat btn-primary" th:href="#{/match/2944107874}">Game Info 2944107874</a>
....
.....
</html>
You should checkout Thymeleaf Standard URL Syntax
So your url will be resolved to
1.http://localhost:2223/my-app-context-path/
2.http://localhost:2223/my-app-context-path/match/2944107874
It depends on your context path, if you are not providing one, you can access mappings directly.
I'm developing a simple Java web application with SpringMVC. With security enabled, I cannot send a HTTP post request (from the index.jsp) to the server although I am already authenticated. POST request does work when the security isn't implemented. So I think it's a problem with my SecurityConfig.java code.Could you please help me with this? Thanks very much
Error Code :
HTTP Status 403 – Forbidden
Type Status Report
Message Forbidden
Description The server understood the request but refuses to authorize it.
This is my security configuration.
SecurityConfig.java
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.HttpMethod;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
#Configuration
#EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
#Autowired
public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
auth.inMemoryAuthentication().withUser("user1").password("{noop}123456").roles("USER");
}
#Override
protected void configure(HttpSecurity http) throws Exception {
http
.formLogin()
.and()
.authorizeRequests()
.antMatchers("/index").hasRole("USER")
.antMatchers(HttpMethod.POST, "/index").hasRole("USER");
}
}
index.jsp
<%# taglib prefix="form" uri="http://www.springframework.org/tags/form"%>
<%#page pageEncoding="UTF-8" contentType="text/html; charset=UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
"http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<META http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Registration</title>
</head>
<body>
<form action='#{/index}' method="POST">
<div class="form-group">
<td><textarea class="form-control" name="textForm">${text1}</textarea>
<input type="submit" value="Submit">
<textarea name="textFin">${textFinal}</textarea></td>
</form>
</div>
</body>
</html>
Add
http.csrf().disable(); to configure method.
protected void configure(HttpSecurity http) throws Exception {
http
.formLogin()
.and()
.authorizeRequests()
.antMatchers("/index").hasRole("USER")
.antMatchers(HttpMethod.POST, "/index").hasRole("USER")
.and()
.csrf().disable();
}
You are confusing jsp with thymleaf. Edit the jsp file to:
<%# taglib prefix="form" uri="http://www.springframework.org/tags/form"%>
<%#page pageEncoding="UTF-8" contentType="text/html; charset=UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
"http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<META http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Registration</title>
</head>
<body>
<form:form action="/index" method="POST">
<div class="form-group">
<td><textarea class="form-control" name="textForm">${text1}</textarea>
<input type="submit" value="Submit">
<textarea name="textFin">${textFinal}</textarea></td>
</form:form>
</div>
</body>
</html>
The UserDetailService bean that you have provided didn't work for me. I had to change it like this:
#Bean
public UserDetailsService userDetailsService() {
// ensure the passwords are encoded properly
#SuppressWarnings("deprecation")
UserBuilder users = User.withDefaultPasswordEncoder();
InMemoryUserDetailsManager manager = new InMemoryUserDetailsManager();
manager.createUser(users.username("me").password("me").roles("USER").build());
return manager;
}
When we enable web security, for every form submitted, we need to send the _crsf(cross-site request forgery) token which is generated randomly base on the user's session.
If we don't want to use this token, we can disable it by calling .csrf().disable()
#Override
protected void configure(HttpSecurity http) throws Exception {
http
.formLogin()
.and()
.authorizeRequests()
.antMatchers("/index").hasRole("USER")
.antMatchers(HttpMethod.POST, "/index").hasRole("USER")
.and()
.csrf().disable();
}
But, in the real world, the token is preferred for security purposes. There are 2 approaches to generate the token.
Approach 1: Generating token automatically by form tag <form:form>. Spring MVC will help us generated the token behind the scenes.
use taglib:
<%# taglib prefix="form" uri="http://www.springframework.org/tags/form" %>
and modify <form action='#{/index}' method="POST"> to:
<form:form action='#{/index}' method="POST">
// our html code
</form:form>
Approach 2: Generating token manually by adding the hidden field.
Before the close form tag </form>, add the following code.
<form action='#{/index}' method="POST">
// our html code
...
<input type="hidden" name="_csrf.parameterName" value="_csrf.token" />
</form>
I'm new at spring, but here I have some problem, and I cant find any answer.
So, I need to set access for a registration page, only for users who have a link from admin. I see that like, admin send the link and only one user can enter and register, after that link will be unavailable.
First of all, I know that admin should generate some link, but I don't know how to.
And I don't know how to set that access from a link. Well, I can say that I don't know anything :)
Can you help me? Like I cant even find some tutorials or information about this.
The code is:
protected void configure(final HttpSecurity http) throws Exception {
http
.csrf().disable()
.authorizeRequests()
.antMatchers("/").permitAll()
.antMatchers("/index").hasAnyRole(USER, ADMIN)
.antMatchers("/admin").hasRole(ADMIN)
.antMatchers("/addUser").hasRole(ADMIN)
.and()
.formLogin()
.loginPage("/login")
.defaultSuccessUrl("/index")
.failureUrl("/login?error")
.usernameParameter("username")
.passwordParameter("password")
.and()
.logout()
.logoutSuccessUrl("/login?logout")
.and()
.exceptionHandling()
.accessDeniedPage("/login")
.and()
.rememberMe()
.rememberMeParameter("remember-me")
.tokenRepository(persistentTokenRepository())
.tokenValiditySeconds(900);
}
Admin page where is button for register new user
<%# page language="java" contentType="text/html; charset=ISO-8859-1" pageEncoding="ISO-8859-1"%>
<%# page isELIgnored="false" %>
<%# taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%# taglib prefix="spring" uri="http://www.springframework.org/tags" %>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<title>Users List</title>
<link href="<c:url value='/resources/css/bootstrap.min.css' />" rel="stylesheet"></link>
</head>
<body>
<div class="generic-container">
<%--<%#include file="authheader.jsp" %>--%>
<div class="panel panel-default">
<!-- Default panel contents -->
<div class="panel-heading"><span class="lead">User Administration</span></div>
<table class="table table-hover">
<thead>
<tr>
<th>Username</th>
<th>Firstname</th>
<th>Lastname</th>
<th>Email</th>
<th>Role</th>
<sec:authorize access="hasRole('ADMIN')">
<th width="100"></th>
</sec:authorize>
<sec:authorize access="hasRole('ADMIN')">
<th width="100"></th>
</sec:authorize>
</tr>
</thead>
<tbody>
<c:forEach items="${users}" var="user">
<tr>
<td>${user.username}</td>
<td>${user.firstname}</td>
<td>${user.lastname}</td>
<td>${user.email}</td>
<td>${user.roles}</td>
<sec:authorize access="hasRole('ROLE_ADMIN')">
<td>edit</td>
</sec:authorize>
<sec:authorize access="hasRole('ROLE_ADMIN')">
<td>delete</td>
</sec:authorize>
</tr>
</c:forEach>
</tbody>
</table>
</div>
<sec:authorize access="hasRole('ADMIN')">
<div class="well">
Add New User
</div>
</sec:authorize>
</div>
</body>
</html>
If you well need some additional code, tell me.
Sorry if something wrong, it's my second question here.
You can generate a token (which will be hard to guess)
UUID id = UUID.randomUUID();
String t = id.toString();
//your link generation goes here
String link = baseUrl+"/register?token="+t;
//Save the token in db with a field expired=false
Token token = new Token();
token.setUuid(t);
token.setCreatedDate(new Date());
token.setExpired(false);
tokenRepo.save(token)
In the request handling, get the token into the RestController and
//let t be the captured token
Token token = tokenRepo.findByUuid(t);
if(token.expired){
//tell them link is expired
}else{
token.setExpired(true)
//give them the reg page and take it from here
}