How to set access for a jsp page, only via link - java

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
}

Related

Redirection Problem from HTTPS Spring Boot app to External HTTPS URLs

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

Href isn't redirecting

I have this code in JSP:
<%# taglib prefix="form" uri="http://www.springframework.org/tags/form" %> <%# taglib prefix="security" uri="http://www.springframework.org/security/tags" %> <%# taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %> <%-- Created by IntelliJ IDEA. User: PC Date: 02.05.2022 Time: 15:20 To change this template use File | Settings | File Templates.
--%> <%# page contentType="text/html;charset=UTF-8" language="java" %>
<html> <head>
<title>Title</title> </head> <body> <h1>Dashboard</h1> <br>
<table>
<tr>
<th>Banners</th>
<th>Localization</th>
</tr>
<%--#elvariable id="banners" type="java.util.List<pl.coderslab.entity.Banners>"--%>
<c:forEach var="banner" items="${banners}">
<tr>
<td>Banner</td>
<td>${banner.street}</td>
<td> <a href="localhost:8080/dashboard/info/${banner.id}" >Wiecej informacji </a></td>
<td> <a href="localhost:8080/dashboard/edit/${banner.id}" >Edytuj </a></td>
<td> <a href="localhost:8080/dashboard/delete/${banner.id}" >Usun </a></td>
</tr>
</c:forEach>
</table>
</body> </html>
and also have controller:
#RequestMapping(value = "/dashboard/info/{id}", method = RequestMethod.GET)
public String showInfo(Model model, #PathVariable("id") int id){
List<Banners> banners = bannerDao.getBannerById(id);
model.addAttribute("banner", banners);
return "showInfo";
}
#RequestMapping(value = "/dashboard/info/{id}", method = RequestMethod.POST)
public String info(){
return "showInfo";
}
The problem is that these href's aren't redirecting. When i click on them nothing happens, as if they were simple buttons. I don't have an idea, what to do here?
1st edit:
Okay so answer from Halil Ibrahim Binol worked but now it shows me 404 error, even if I have #RequestMapping to this address
Did you try adding http prefix?
<a href="http://localhost:8080/dashboard/info/${banner.id}" >Wiecej informacji</a>
Or you can use;
Wiecej informacji
This will be use current page protocol. When you are in https page it will convert to https://localhost:8080/...
Edit:
Alternatively, when your code is running in same server. You can use;
Wiecej informacji

SpringMVC (Security) - 403 error

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>

Model attribute is not available as request attribute in JSP page

I am trying to create a sample registration page with Spring MVC and JSP pages.
While opening the url on tomcat server, I am getting following error
root cause
java.lang.IllegalStateException: Neither BindingResult nor plain target object for bean name 'register' available as request attribute
org.springframework.web.servlet.support.BindStatus.<init>(BindStatus.java:144)
org.springframework.web.servlet.tags.form.AbstractDataBoundFormElementTag.getBindStatus(AbstractDataBoundFormElementTag.java:168)
org.springframework.web.servlet.tags.form.AbstractDataBoundFormElementTag.getPropertyPath(
I have a JSP register.jsp
<%# taglib prefix="form" uri="http://www.springframework.org/tags/form"%>
<%# page language="java" contentType="text/html; charset=ISO-8859-1"
pageEncoding="ISO-8859-1"%>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<title>Registration</title>
</head>
<body>
<form:form action="/register/process" method="POST" modelAttribute="register">
<table style="text-align: center;">
<tr>
<td><form:label path="fname">First Name</form:label></td>
<td><form:input path="fname" name="fname"
id="fname" /></td>
</tr>
<tr>
<td><form:label path="lname">Last Name</form:label></td>
<td><form:input path="lname" name="lname" id="lname" />
</td>
</tr>
<tr>
<td></td>
<td>
<input type="submit" value="CREATE AN ACCOUNT"/>
</td>
</tr>
</table>
</form:form>
</body>
</html>
I have a controller class UserController.java
package vnfhub.supplier.controller;
#Controller
public class UserController {
#RequestMapping(value = "/register", method = RequestMethod.GET)
public String getRegisterForm(Model model) {
model.addAttribute("register", new Register());
return "register";
}
#RequestMapping(value = "/register/process", method = RequestMethod.POST)
public String processRegistration(#ModelAttribute("register") Register register, BindingResult result) {
return "success";
}
}
and a success.jsp page
<%# page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="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>Success Form</title>
</head>
<body>
<font color="green"><h1>Hello</h1></font>
<h1>You have successfully registered</h1>
<font color="green"><h1>Welcome to Spring world !</h1></font>
</body>
</html>
I have tried many solution on stackoverflow.... but none of them worked.
I find your code okay so far as you given here. I mimic the situation with your code but unfortuantely found No Exception.
Things that you might have doing wrong is you are running some old build code in your tomcat. try to clean build and re-deploy in your container.
NB: one friendly suggestion. You are doing one thing wrong that is having action of your form to /register/process that will send the request to the container root (e.g. localhost:8080/register/process). And you will get 404 for that. You are not probably want that. register/process should be your URL and this will POST the request relative to your application-context. If your application context is something localhost:8080/test, this will send the request to localhost:8080/test/register/process

struts resource bundle properties file not mapping some keys

I'm starting to study struts and I have a problem using resource properties file
some text on page is displayed as this:
???login.message???
???login.username???
???login.password???
but some other messages are correctly taken from properties file. I think that the propertis file is correctly configured but I'm missing something to display anything correctly.
the file ApplicationResources.properties
# Resources for Login Project
# Struts Validator Error Messages
# These two resources are used by Struts HTML tag library
# to format messages. In this case we make sure that errors
# are red so that they can be noticed.
errors.header=<font color="red">*
errors.footer=</font>
#errors associated with the Login page
error.username.required=username required.
error.password.required=password required
error.login.invalid=The system could not verify your username or password. Is your CAPS LOCK on? Please try again.
#login page text
login.title=this is a title
login.message=please log in
login.username=username:
login.password=password:
login.button.signon=Log In
#loggedin page text
loggedin.title=Login Project
loggedin.msg=Benvenuto, {0}. You are now logged in.
"error.login.invalid" is correctly displayed and "error.username.required" too
the login label not
this is my jsp page
<%# page language="java" contentType="text/html; charset=ISO-8859-1"
pageEncoding="ISO-8859-1"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<%# taglib uri="http://java.sun.com/jstl/fmt" prefix="fmt" %>
<%# taglib uri="http://struts.apache.org/tags-html" prefix="html" %>
<html:html locale="true"/>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<fmt:bundle basename="ApplicationResources"/>
<title><fmt:message key="login.title"/></title>
</head>
<body>
<html:errors property="login"/>
<html:form action="login.do" focus="userName" >
<table align="center">
<tr align="center">
<td><H1><fmt:message key="login.message"/></H1></td>
</tr>
<tr align="center">
<td>
<table align="center">
<tr>
<td align="right">
<fmt:message key="login.username"/>
</td>
<td align="left">
<html:text property="userName"
size="15"
maxlength="15" />
<html:errors property="userName" />
</td>
</tr>
<tr>
<td align="right">
<fmt:message key="login.password"/>
</td>
<td align="left">
<html:password property="password"
size="15"
maxlength="15"
redisplay="false"/>
<html:errors property="password" />
</td>
</tr>
<tr>
<td colspan="2" align="center">
<html:submit>
<fmt:message key="login.button.signon"/>
</html:submit>
</td>
</tr>
</table>
</td>
</tr>
</table>
</html:form>
</body>
</html>
Can you help me ?
tkz
Your
<fmt:message ... />
tags need to be inside an
<fmt:bundle ... >
tag. Currently you are closing your bundle tag right away
<fmt:bundle basename="ApplicationResources"/>
Instead, open it
<fmt:bundle basename="ApplicationResources">
and close it
</fmt:bundle>
when you no longer need it, possibly at the end of your JSP. Nest your
<fmt:message key="login.title"/>
tags inside it.

Categories