This is sample application for develop using TERASOLUNA Server Framework for Java (5.x).
Currently, this application is under developing !!!
This application is developed based TERASOLUNA Server Framework for Java (5.x) Development Guideline.
But it being customized by my opinion in the partially (this means is not 100% compliance by guideline).
Structure of this application is following.
Layer | Component/Library | Main responsibilities |
---|---|---|
Client Layer | jQuery 3.5.1 | Provide the useful javascript operations. |
AngularJS 1.2.32 | Provide the JavaScript MVW Framework. | |
Bootstrap 3.4.1 | Provide the useful & stylish css configurations, and provide the useful client components(alert, message dialog, etc..). | |
Server Side Platform | Java SE 8 Java Virtual Machine | Provide the execution environment for Java application. |
Java EE 7 Servlet Container | Provide the servlet engine that supports servlet 3.1 specification. | |
Spring Framework 5.2.3.RELEASE | Provide mechanism of CDI(Context and Dependency Inject). In this application, use the transaction management and AOP mechanism. | |
Application Layer | Spring Security 5.2.1.RELEASE | Provide mechanism of security on web application. |
Spring MVC 5.2.3.RELEASE | Provide mechanism of Java MVC Framework for web application. | |
Bean Validation 2.0(JSR-380) | Provide mechanism of validation for request data. In this application, use Hibernate Validator 6.0.18.Final as implementation provider. | |
Controller | Handle a request & delegate a business procedure to the services. | |
DTO | Hold transfer data(form data or resource data) of application layer(web layer). | |
JSP | Generate presentation component(HTML) by accessing to DTO and Domain Object via Model object or RedirectAttributes provided by Spring MVC. |
|
Domain Layer | Domain Object | Hold domain data & implements core business logic. |
Repository | Define & provide CRUD operations(interfaces) to the Domain objects. | |
Service | Implements & provide business procedure(Part of the business logic) and provide transaction boundary. | |
Infrastructure Layer | MyBatis 3.5.3 | Provide mechanism of database access. In this application, use the Mapper interface as Repository interface. SQL is implements in Mapper MXL. |
Libraries | TERASOLUNA Server Framework for Java (5.x) Common Library 5.6.0.RELEASE | Provide useful functionalities(Transaction Token Check, Codelist, Pagination, MessageManagement, ExceptionHandling, etc..) on develop enterprise application. And provide dependency on useful OSS libraries(Dozer, Joda-Time, Apache-Commons families, etc..). |
The following libraries is dependency for application-specific without relate on TERASOLUNA Server Framewrok for Java (5.x).
Library(Group Id:Artifact Id) | Version | Description |
---|---|---|
com.h2database:h2 | 1.4.200 * | Depends on to access H2 database. |
org.projectlombok:lombok | 1.18.10 * | Depends on for automatically generate a methods(getter/setter/etc ...) of JavaBean. By the this library use, we can develop smoothly and effectively. If you are use IDE as Eclispe or STS(Spring Tool Suite) or IDEA or NetBeans, please install lombok.jar to the IED. In detail of how to install, please see here. (If IDEA , please install lombok plugin) |
org.springframework.hateoas:spring-hateoas | 1.0.3.RELEASE * | Depends on to support HATEOAS as REST API. |
io.github.bonigarcia:webdrivermanager | 4.0.0 | Depends on download an execution file of selenium WebDrivier . (test scope) |
* The version is managed by Spring Boot Dependency via TERASOLUNA Server Framewrok for Java (5.x) parent project.
The following libraries are version up from version that TERASOLUNA Server Framework for Java (5.x) depend on. Reason of version up is to try the latest version.
Library | In this application | TERASOLUNA Server Framework for Java (5.x) |
---|
Description coming soon...
Description coming soon...
Description coming soon...
Functionalities of this application are follows.
No | Functionality name | Description |
---|---|---|
1 | Welcome page | Coming soon... |
2 | Authentication | Coming soon... |
3 | Authorization | Coming soon... |
4 | Security Countermeasure | Coming soon... |
5 | Session Management | Coming soon... |
6 | Accounts Management | Coming soon... |
7 | My Profile Management | Coming soon... |
8 | Password Management | Coming soon... |
9 | Time Card | Coming soon... |
10 | Others... | Coming soon... |
This section describe about authentication in this application.
In this application, authentication(login and logout) processing are implements using Spring Security and Spring MVC.
Responsibility of each other are following.
- Spring Security has responsible for the authentication processing.
- Spring MVC has responsible for input values validation and the screen control.
Display processing flow of login form are following.
If access the protected page when not authenticate, spring-security redirect to the uri(page) that is defined in login-page
attribute of sec:form-login
element.
src/main/resources/META-INF/spring/spring-security.xml
<sec:http auto-config="true" use-expressions="true">
<!-- omit -->
<sec:form-login login-processing-url="/auth/authenticate" login-page="/auth/login?encourage"
username-parameter="accountId" password-parameter="password"
authentication-details-source-ref="customAuthenticationDetailsSource"
authentication-failure-handler-ref="authenticationFailureHandler" />
<!-- omit -->
</sec:http>
Request of GET /auth/login?encourage
and GET /auth/login
are handled LoginController
.
In the LoginController
, set the message and view the login form page.
src/main/java/com/github/kazuki43zoo/app/auth/LoginController.java
@RequestMapping("auth/login")
@Controller
public class LoginController {
// omit
@TransactionTokenCheck(type = TransactionTokenType.BEGIN)
@RequestMapping(method = RequestMethod.GET)
public String showLoginForm() {
return "auth/loginForm";
}
@RequestMapping(method = RequestMethod.GET, params = "encourage")
public String encourageLogin(RedirectAttributes redirectAttributes) {
redirectAttributes.addFlashAttribute(Message.AUTH_ENCOURAGE_LOGIN.buildResultMessages());
return "redirect:/auth/login";
}
// omit
}
When view the login form page, global transaction for transaction token check is begun.
Generate screen data(response data) by the auth/loginForm
view(JSP).
src/main/webapp/WEB-INF/views/auth/loginForm.jsp
<c:if test="${!param.including}">
<t:messagesPanel messagesAttributeName="SPRING_SECURITY_LAST_EXCEPTION" messagesType="danger" />
<t:messagesPanel />
<spring:hasBindErrors name="loginForm">
<spring:nestedPath path="loginForm">
<div class="alert alert-danger">
<form:errors path="*" />
</div>
</spring:nestedPath>
</spring:hasBindErrors>
</c:if>
<form:form action="${contextPath}/auth/login" class="navbar-form" method="post" modelAttribute="loginForm">
<div class="form-group">
<form:input type="text" path="accountId" class="form-control" placeholder="Account ID" />
</div>
<div class="form-group">
<form:password path="password" class="form-control" placeholder="Password" />
</div>
<button class="btn">
<span class="glyphicon glyphicon-log-in"></span>
</button>
</form:form>
loginForm.jsp
is included from thesrc/main/webapp/WEB-INF/views/common/layout/topNavbar.jsp
. Hence, in this JSP, use theincluding
parameter to judge the included / not included. When are included fromtopNavbar.jsp
, error message does not displayed in this page.
Login processing flow are following.
In this application, parameter name of username and password has change the default settings of Spring Security.
src/main/webapp/WEB-INF/views/auth/loginForm.jsp
<form:form action="${contextPath}/auth/login" class="navbar-form" method="post" modelAttribute="loginForm">
<div class="form-group">
<form:input type="text" path="accountId" class="form-control" placeholder="Account ID" />
</div>
<div class="form-group">
<form:password path="password" class="form-control" placeholder="Password" />
</div>
<button class="btn">
<span class="glyphicon glyphicon-log-in"></span>
</button>
</form:form>
In this application, LoginController
receive the login request, and execute validation of login form data. If not exists violation, LoginContoller
forward to the authentication processing of Spring Security.
If not exists requirement as input value validation or re-display, Spring MVC is not required.
src/main/java/com/github/kazuki43zoo/app/auth/LoginController.java
@RequestMapping("auth/login")
@Controller
public class LoginController {
// omit
@TransactionTokenCheck
@RequestMapping(method = RequestMethod.POST)
public String login(@Validated LoginForm form, BindingResult bindingResult) {
if (bindingResult.hasErrors()) {
return showLoginForm();
}
return "forward:/auth/authenticate";
}
// omit
}
In the login processing , execute global transaction token check. Global transaction are begin when view the welcom page or the login page.
src/main/java/com/github/kazuki43zoo/app/auth/LoginForm.java
@AllArgsConstructor
@NoArgsConstructor
@Data
public class LoginForm implements Serializable {
private static final long serialVersionUID = 1L;
@NotNull
private String accountId;
@NotNull
private String password;
}
For forward to the authentication processing of Spring Security, as the settings ofSpringSecurityFilterChain
, need add<dispatcher>FORWARD</dispatcher>
.
src/main/webapp/WEB-INF/web.xml
<filter>
<filter-name>SpringSecurityFilterChain</filter-name>
<filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
<init-param>
<param-name>targetBeanName</param-name>
<param-value>springSecurityFilterChain</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>SpringSecurityFilterChain</filter-name>
<url-pattern>/auth/authenticate</url-pattern>
<dispatcher>FORWARD</dispatcher>
</filter-mapping>
<filter-mapping>
<filter-name>SpringSecurityFilterChain</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
Spring Security execute the authentication processing when was accessed to the url that is defined in login-processing-url
attribute of sec:form-login
element.
In this application, login-processing-url
& username-parameter
& password-parameter
attribute of sec:form-login
element has change the default settings of Spring Security.
Reason of changing default settings is to hide the fact that are using the Spring Security as security countermeasure. If occur the security vulnerability in the Spring Security, be able to reduce the risk of attack to this application.
src/main/resources/META-INF/spring/spring-security.xml
<sec:http auto-config="true" use-expressions="true">
<!-- omit -->
<sec:form-login login-processing-url="/auth/authenticate" login-page="/auth/login?encourage"
username-parameter="accountId" password-parameter="password"
authentication-details-source-ref="customAuthenticationDetailsSource"
authentication-failure-handler-ref="authenticationFailureHandler" />
<!-- omit -->
</sec:http>
In this application, authentication realize using the DaoAuthenticationProvider
of Spring Security.
DaoAuthenticationProvider
has authenticate by using the user information that are loaded from the data store.
In DaoAuthenticationProvider
, be able to check for the status of loaded user. Actually checking contents are following.
User information are loaded as instance of theCustomUserDetails
(extended class in this application). In this application, load the user information via theCustomUserDetailService
(extended class in this application).
No | Checking content | Specification in this application |
---|---|---|
1 | Specified user exists ? | Fetches the record that matches specified account id from the account table. If not exists matched record, occur the authentication error. |
2 | Specified user is not lock ? | Fetches the password failure count of fetched account. If it is over the max count of password failure count, occur the authentication error. |
3 | Specified user is enable ? | Fetches the enable flag of fetched account. If it is false(disabled), occur the authentication error. |
4 | Specified user is not expired ? | In this application, not support this checking. This means that check result is OK at always. |
5 | Specified user's password is not expired ? | Fetches the last modified date time of password. If it not modified during the password valid days period, encourage the password changing. |
6 | Matches the specified password ? | Fetches the password. If it not matches the specified password, occur the authentication error as bad credential. |
src/main/resources/META-INF/spring/spring-security.xml
<sec:authentication-manager>
<sec:authentication-provider user-service-ref="customUserDetailsService">
<sec:password-encoder ref="passwordEncoder" />
</sec:authentication-provider>
</sec:authentication-manager>
customUserDetailsService
are scan by component-scan.passwordEncoder
are defined insrc/main/resources/META-INF/spring/applicationContext.xml
. In this application, use theBCryptPasswordEncoder
.
description coming soon...
description coming soon...
description coming soon...
description coming soon...
Coming soon...
This section describe about authorization in this application.
In this application, authorization(access control of protected page) processing are implements using Spring Security.
Coming soon...
This section describe about other security countermeasure in this application.
Coming soon...
src/main/resources/META-INF/spring/spring-security.xml
<sec:http auto-config="true" use-expressions="true">
<!-- omit -->
<sec:session-management invalid-session-url="/error/invalidSession"
session-fixation-protection="migrateSession" />
<!-- omit -->
</sec:http>
Coming soon...
src/main/resources/META-INF/spring/spring-security.xml
<sec:http auto-config="true" use-expressions="true">
<!-- omit -->
<sec:csrf request-matcher-ref="csrfRequestMatcher" />
<!-- omit -->
</sec:http>
<bean id="csrfRequestMatcher" class="org.springframework.security.web.util.matcher.AndRequestMatcher">
<constructor-arg>
<list>
<bean class="org.springframework.security.web.csrf.CsrfFilter$DefaultRequiresCsrfMatcher"/>
<bean class="org.springframework.security.web.util.matcher.NegatedRequestMatcher">
<constructor-arg ref="csrfExclusionPathMatcher" />
</bean>
</list>
</constructor-arg>
</bean>
<bean id="csrfExclusionPathMatcher" class="org.springframework.security.web.util.matcher.OrRequestMatcher">
<constructor-arg>
<list>
<bean class="org.springframework.security.web.util.matcher.AntPathRequestMatcher">
<constructor-arg index="0" value="/vendor/h2/**" />
</bean>
</list>
</constructor-arg>
</bean>
Coming soon...
src/main/resources/META-INF/spring/spring-security.xml
<sec:http auto-config="true" use-expressions="true">
<!-- omit -->
<sec:headers>
<!-- omit -->
<sec:content-type-options />
<sec:xss-protection/>
</sec:headers>
<!-- omit -->
</sec:http>
Coming soon...
src/main/resources/META-INF/spring/spring-security.xml
<sec:http auto-config="true" use-expressions="true">
<!-- omit -->
<sec:headers>
<!-- omit -->
<sec:frame-options policy="SAMEORIGIN" />
<!-- omit -->
</sec:headers>
<!-- omit -->
</sec:http>
Coming soon...
src/main/resources/META-INF/spring/spring-security.xml
<sec:http auto-config="true" use-expressions="true">
<!-- omit -->
<sec:headers>
<sec:cache-control />
<!-- omit -->
</sec:headers>
<!-- omit -->
</sec:http>
Coming soon...
src/main/resources/META-INF/spring/spring-security.xml
<sec:http auto-config="true" use-expressions="true">
<!-- omit -->
<sec:headers>
<!-- omit -->
<sec:hsts />
<!-- omit -->
</sec:headers>
<!-- omit -->
</sec:http>
This section describe about session management in this application.
Coming soon...