Improvements to authorization
This commit is contained in:
parent
ec17e0d72a
commit
21d4f58574
|
@ -12,27 +12,22 @@ import com.mousetech.gourmetj.persistence.model.Recipe;
|
|||
import com.mousetech.gourmetj.persistence.service.RecipeService;
|
||||
|
||||
import jakarta.annotation.PostConstruct;
|
||||
import jakarta.enterprise.context.RequestScoped;
|
||||
import jakarta.faces.event.AjaxBehaviorEvent;
|
||||
import jakarta.faces.model.DataModel;
|
||||
import jakarta.faces.model.ListDataModel;
|
||||
import jakarta.faces.view.ViewScoped;
|
||||
import jakarta.inject.Inject;
|
||||
import jakarta.inject.Named;
|
||||
|
||||
/**
|
||||
* Main control panel backing bean.
|
||||
*
|
||||
* The rare and fabled RequestScope, which is otherwise
|
||||
* useless 90% of the time. Here we maintain no session
|
||||
* state. so we can better support the session timeout
|
||||
* for editing functions.
|
||||
*
|
||||
* @author timh
|
||||
* @since Jun 28, 2012
|
||||
*/
|
||||
|
||||
@Named
|
||||
@RequestScoped
|
||||
@ViewScoped
|
||||
public class AdminMainBean implements Serializable {
|
||||
|
||||
/**
|
||||
|
@ -49,9 +44,6 @@ public class AdminMainBean implements Serializable {
|
|||
private static final Logger log =
|
||||
LoggerFactory.getLogger(AdminMainBean.class);
|
||||
|
||||
/** Cookie delimiter */
|
||||
private static final String CKDLM = ",";
|
||||
|
||||
/**
|
||||
* Persistency service for Recipes.
|
||||
*/
|
||||
|
@ -289,4 +281,9 @@ public class AdminMainBean implements Serializable {
|
|||
// items.
|
||||
return "recipeDetails?faces-redirect=true";
|
||||
}
|
||||
|
||||
public String doLogout() {
|
||||
JSFUtils.logout();
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -165,4 +165,8 @@ public class JSFUtils {
|
|||
}
|
||||
|
||||
}
|
||||
|
||||
public static HttpSession getSession(boolean create) {
|
||||
return (HttpSession) getExternalContext().getSession(create);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -14,12 +14,10 @@ import jakarta.faces.model.ListDataModel;
|
|||
import jakarta.faces.view.ViewScoped;
|
||||
import jakarta.inject.Inject;
|
||||
import jakarta.inject.Named;
|
||||
import jakarta.servlet.http.Part;
|
||||
import jakarta.faces.event.AjaxBehaviorEvent;
|
||||
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.primefaces.event.FileUploadEvent;
|
||||
import org.primefaces.model.file.UploadedFile;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
|
@ -980,7 +978,7 @@ public class RecipeDetailBean implements Serializable {
|
|||
|
||||
public String editDescription() {
|
||||
this.setDetailTab(0);
|
||||
return "detailEdit?faces-redirect=true";
|
||||
return "detailEdit.xhtml?faces-redirect=true";
|
||||
}
|
||||
|
||||
public String editIngredients() {
|
||||
|
|
|
@ -21,10 +21,11 @@ import org.springframework.http.HttpStatus;
|
|||
"com.mousetech.gourmetj.persistence.model" })
|
||||
public class SpringPrimeFacesApplication {
|
||||
|
||||
final String homePage = "/main.jsf?viewExpired=true";
|
||||
final String errorPage = "/error/error.html";
|
||||
final String error404Page = "/error/error404.html";
|
||||
final String error404Page = "/error/error404.jsp";
|
||||
final String error400Page = "/error/error400.jsp";
|
||||
final String expiredPage = "/main.xhtml";
|
||||
final String expiredPage = "/error/viewExpired.xhtml";
|
||||
|
||||
public static void main(String[] args) {
|
||||
SpringApplication.run(SpringPrimeFacesApplication.class,
|
||||
|
|
|
@ -20,6 +20,7 @@ import org.springframework.security.config.annotation.web.configuration.EnableWe
|
|||
import org.springframework.security.config.annotation.web.configuration.WebSecurityCustomizer;
|
||||
import org.springframework.security.config.annotation.web.configurers.AbstractHttpConfigurer;
|
||||
import org.springframework.security.web.SecurityFilterChain;
|
||||
import org.springframework.security.web.authentication.LoginUrlAuthenticationEntryPoint;
|
||||
|
||||
import jakarta.servlet.DispatcherType;
|
||||
|
||||
|
@ -99,23 +100,23 @@ public class SpringSecurityConfig {
|
|||
return ocreds;
|
||||
}
|
||||
|
||||
@Bean
|
||||
SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
|
||||
@Bean
|
||||
SecurityFilterChain securityFilterChain(HttpSecurity http)
|
||||
throws Exception {
|
||||
|
||||
http
|
||||
.csrf(AbstractHttpConfigurer::disable)
|
||||
.cors(AbstractHttpConfigurer::disable)
|
||||
.formLogin(formLogin ->
|
||||
formLogin
|
||||
.loginPage("/login.xhtml")
|
||||
.permitAll())
|
||||
.authorizeHttpRequests((authorize)-> authorize
|
||||
.dispatcherTypeMatchers(DispatcherType.FORWARD, DispatcherType.ERROR).permitAll()
|
||||
.anyRequest().authenticated()
|
||||
);
|
||||
http.csrf(AbstractHttpConfigurer::disable)
|
||||
.cors(AbstractHttpConfigurer::disable)
|
||||
.formLogin(login -> login.loginPage("/login.jsf")
|
||||
.permitAll()
|
||||
.failureUrl("/login.jsf?error=true"))
|
||||
.logout(logout -> logout
|
||||
.logoutSuccessUrl("/login.jsf"))
|
||||
.httpBasic(Customizer.withDefaults())
|
||||
.authorizeHttpRequests((authorize) -> authorize
|
||||
.anyRequest().authenticated());
|
||||
|
||||
return http.build();
|
||||
}
|
||||
return http.build();
|
||||
}
|
||||
|
||||
/**
|
||||
* Replaces old antMatchers for determining secured URLs.
|
||||
|
@ -124,14 +125,19 @@ public class SpringSecurityConfig {
|
|||
@Bean
|
||||
public WebSecurityCustomizer webSecurityCustomizer() {
|
||||
return (web) -> web.ignoring().requestMatchers(
|
||||
"/jakarta.faces.resource/**",
|
||||
"/index.xhtml",
|
||||
"/jakarta.faces.resource/**",
|
||||
"/",
|
||||
"/index.jsf",
|
||||
"/login",
|
||||
"/index.html",
|
||||
// "/login",
|
||||
// "/login.jsf", // Leave them for the authenticator!
|
||||
// "/login.xhtml",
|
||||
"/main.jsf",
|
||||
"/main.xhtml",
|
||||
"/img/**",
|
||||
"/error/**",
|
||||
"/RES_NOT_FOUND",
|
||||
"/recipeDetails.jsf",
|
||||
"/recipeDetails.xhtml",
|
||||
"/shoppingList.jsf",
|
||||
"/recipePrint.jsf");
|
||||
}
|
||||
|
|
|
@ -5,10 +5,8 @@ import java.util.ArrayList;
|
|||
import java.util.List;
|
||||
|
||||
import jakarta.enterprise.context.SessionScoped;
|
||||
import jakarta.faces.model.SelectItem;
|
||||
import jakarta.inject.Named;
|
||||
|
||||
import org.primefaces.PrimeFaces;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
|
|
|
@ -25,7 +25,7 @@
|
|||
<navigation-case>
|
||||
<description>Go Home</description>
|
||||
<from-outcome>home</from-outcome>
|
||||
<to-view-id>/main</to-view-id>
|
||||
<to-view-id>/main.xhtml?faces-redirect=true</to-view-id>
|
||||
<redirect />
|
||||
</navigation-case>
|
||||
</navigation-rule>
|
||||
|
|
|
@ -1,12 +0,0 @@
|
|||
<!DOCTYPE html>
|
||||
<html xmlns="http://www.w3.org/1999/xhtml">
|
||||
<html>
|
||||
<head>
|
||||
<title>ERROR - Page Not Found</title>
|
||||
</head>
|
||||
<body>
|
||||
<h1>Page Not Found</h1>
|
||||
<p>This URL is invalid.</p>
|
||||
<p><a href="/main.jsf">Return to Main Page</a></p>
|
||||
</body>
|
||||
</html>
|
12
src/main/resources/META-INF/resources/error/error404.jsp
Normal file
12
src/main/resources/META-INF/resources/error/error404.jsp
Normal file
|
@ -0,0 +1,12 @@
|
|||
<%@ page language="java" contentType="text/html; charset=US-ASCII"
|
||||
pageEncoding="US-ASCII" isErrorPage="true"%>
|
||||
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "https://www.w3.org/TR/html4/loose.dtd">
|
||||
<html xmlns="http://www.w3.org/1999/xhtml">
|
||||
<head>
|
||||
<title>ERROR - Page Not Found</title>
|
||||
</head>
|
||||
<body>
|
||||
<h1>Page Not Found</h1>
|
||||
<p><a href="/main.jsf">Return to Main Page</a></p>
|
||||
</body>
|
||||
</html>
|
|
@ -1,14 +0,0 @@
|
|||
<!DOCTYPE html>
|
||||
<html xmlns="http://www.w3.org/1999/xhtml">
|
||||
<head>
|
||||
<title>ERROR - Page Expired</title>
|
||||
</head>
|
||||
<body>
|
||||
<h1>Page Expired</h1>
|
||||
<p>The page state could not be restored because it was
|
||||
left idle too long.</p>
|
||||
<p>
|
||||
<a href="/main.jsf">Return to Main Page</a>
|
||||
</p>
|
||||
</body>
|
||||
</html>
|
|
@ -1,13 +1,8 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE html>
|
||||
<html xmlns="http://www.w3.org/1999/xhtml"
|
||||
xmlns:h="http://xmlns.jcp.org/jsf/html"
|
||||
xmlns:f="http://xmlns.jcp.org/jsf/core"
|
||||
xmlns:ui="http://java.sun.com/jsf/facelets"
|
||||
xmlns:p="http://primefaces.org/ui"
|
||||
>
|
||||
<h:head>Gourmet Recipe Manager</h:head>
|
||||
<h:body>
|
||||
<html>
|
||||
<head><title>Gourmet Recipe Manager</title><head>
|
||||
<body>
|
||||
<h1>Gourmet Recipe Manager</h1>
|
||||
<p>This is an implementation of Thomas Hinkle's
|
||||
Gourmet Recipe Manager, originally a desktop
|
||||
|
@ -20,5 +15,5 @@
|
|||
<p>This is an open-source application under the
|
||||
Common Development and Distribution License (CDDL).
|
||||
</p>
|
||||
</h:body>
|
||||
<body>
|
||||
</html>
|
|
@ -1,31 +1,36 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
|
||||
<!DOCTYPE html>
|
||||
<html xmlns="http://www.w3.org/1999/xhtml"
|
||||
xmlns:h="http://java.sun.com/jsf/html"
|
||||
xmlns:f="http://xmlns.jcp.org/jsf/core"
|
||||
xmlns:p="http://primefaces.org/ui"
|
||||
xmlns:pe="http://primefaces.org/ui/extensions">
|
||||
|
||||
xmlns:h="http://java.sun.com/jsf/html"
|
||||
xmlns:f="http://xmlns.jcp.org/jsf/core"
|
||||
xmlns:p="http://primefaces.org/ui"
|
||||
xmlns:pe="http://primefaces.org/ui/extensions"
|
||||
>
|
||||
<h:head>
|
||||
<title>Login</title>
|
||||
<h:outputStylesheet name="/css/login.css" />
|
||||
<title>Login</title>
|
||||
</h:head>
|
||||
|
||||
<h:body>
|
||||
<h:form prependId="false">
|
||||
|
||||
<p:panelGrid columns="1" styleClass="ui-fluid center ui-noborder">
|
||||
<h2>Please login</h2>
|
||||
|
||||
<p:outputLabel value="Login failed!" styleClass="red"
|
||||
rendered="${!empty param['error']}" />
|
||||
|
||||
<p:inputText id="username" placeholder="User name" />
|
||||
<p:password id="password" placeholder="Password" />
|
||||
|
||||
<p:commandButton value="Login" ajax="false" />
|
||||
</p:panelGrid>
|
||||
|
||||
</h:form>
|
||||
<h:form prependId="false" style="width:100%">
|
||||
<p:panelGrid columns="3" style="width:100%"
|
||||
styleClass="ui-fluid center ui-noborder"
|
||||
>
|
||||
<h:outputText style="width:33%;" value=" " />
|
||||
<p:panelGrid columns="1" id="grid1">
|
||||
<h:outputText>Please login</h:outputText>
|
||||
<p:outputLabel value="Login failed!"
|
||||
styleClass="red"
|
||||
rendered="${!empty param['error']}"
|
||||
/>
|
||||
<p:outputLabel for="username">User ID</p:outputLabel>
|
||||
<p:inputText id="username"
|
||||
placeholder="User name"
|
||||
/>
|
||||
<p:outputLabel for="password">Password</p:outputLabel>
|
||||
<p:password id="password" placeholder="Password" />
|
||||
<p:commandButton value="Login" ajax="false" />
|
||||
</p:panelGrid>
|
||||
<h:outputText style="width:33%;" value=" " />
|
||||
</p:panelGrid>
|
||||
</h:form>
|
||||
</h:body>
|
||||
</html>
|
|
@ -20,13 +20,7 @@
|
|||
listener="#{adminMainBean.ajaxUpdateList}"
|
||||
/>
|
||||
</p:autoComplete>
|
||||
<p:defaultCommand target="find" />
|
||||
<p:commandButton id="find" value="Find"
|
||||
icon="ui-icon-search"
|
||||
action="#{adminMainBean.doFind}"
|
||||
update=":form2:table1"
|
||||
/>
|
||||
<p:outputLabel for="@next" value="Search for " />
|
||||
<p:outputLabel for="@next" value=" In " />
|
||||
<p:selectOneMenu id="ctlSearchType"
|
||||
value="#{cookieBean.searchType}"
|
||||
>
|
||||
|
@ -37,6 +31,12 @@
|
|||
listener="#{adminMainBean.resetSuggestions}"
|
||||
/>
|
||||
</p:selectOneMenu>
|
||||
<p:defaultCommand target="find" />
|
||||
<p:commandButton id="find" value="Find"
|
||||
icon="ui-icon-search"
|
||||
action="#{adminMainBean.doFind}"
|
||||
update=":form2:table1"
|
||||
/>
|
||||
<p:commandButton id="ctlClear" value="Clear"
|
||||
icon="ui-icon-close"
|
||||
update="@form:searchFor :form2:table1"
|
||||
|
@ -55,6 +55,9 @@
|
|||
<h:outputLabel for="slistSize"
|
||||
value=" Recipes in Shopping List"
|
||||
/>
|
||||
<p:commandButton id="logout" value="Logout"
|
||||
action="#{adminMainBean.doLogout}"
|
||||
/>
|
||||
</div>
|
||||
</h:form>
|
||||
<h:form id="form2">
|
||||
|
|
|
@ -21,10 +21,13 @@ spring:
|
|||
ddl-auto: none
|
||||
database-platform: org.hibernate.dialect.MySQLDialect
|
||||
|
||||
# Tracking-modes prevent URL rewrite jsessionid on Primecases
|
||||
# resources. Which causes "400" errors on initial main.jsf fetch.
|
||||
server:
|
||||
servlet:
|
||||
session:
|
||||
timeout: '30m'
|
||||
tracking-modes: 'cookie'
|
||||
# Theme here overrides joinfaces theme
|
||||
# context-parameters:
|
||||
# primefaces:
|
||||
|
@ -38,3 +41,14 @@ gourmet:
|
|||
joinfaces:
|
||||
primefaces:
|
||||
theme: bluesky
|
||||
faces:
|
||||
project-stage: Production
|
||||
facelets-libraries: /tags/tags.taglib.xml
|
||||
|
||||
#logging:
|
||||
# level:
|
||||
# org.springframework.security: TRACE
|
||||
# org.apache.catalina: TRACE
|
||||
# jakarta.faces: TRACE
|
||||
# com.sun.faces: TRACE
|
||||
# jakarta.servlet: TRACE
|
Loading…
Reference in New Issue
Block a user