I have working XML-based security configuration in my Spring MVC project:
<security:http use-expressions="true"
authentication-manager-ref="authenticationManager">
<security:intercept-url pattern="/" access="permitAll"/>
<security:intercept-url pattern="/dashboard/home/**" access="hasAnyRole('ROLE_USER, ROLE_ADMIN')"/>
<security:intercept-url pattern="/dashboard/users/**" access="hasRole('ROLE_ADMIN')"/>
<security:intercept-url pattern="/rest/users/**" access="hasRole('ROLE_ADMIN')"/>
<security:form-login login-page="/"/>
</security:http>
And I have question: is it possible to fully replace it by Java configuration? What annotations and where should I use for "use-expressions", "intercept-url", etc.?
Yes, if you are using Spring security 3.2 and above, it will be something like this :
#Configuration
#EnableWebSecurity
public class MyWebSecurityConfiguration extends WebSecurityConfigurerAdapter {
#Override
public void configure(WebSecurity web) throws Exception {
web.ignoring().antMatchers("/resources/**");
}
#Override
protected void configure(HttpSecurity http) throws Exception {
http
.authorizeRequests()
.antMatchers("/").permitAll()
.antMatchers("/dashboard/home/**").hasAnyRole("USER", "ADMIN")
.antMatchers("/dashboard/users/**").hasRole("ADMIN")
.antMatchers("/rest/users/**").hasRole("ADMIN")
.anyRequest().authenticated()
.and()
.formLogin()
.loginPage("/")
.permitAll();
}
// Possibly more overridden methods ...
}
Related
I'm using Spring Boot MVC last version (5.3) e Spring security (5.5) with LDAP users
I'm trying to change from this xml
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:security="http://www.springframework.org/schema/security"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.2.xsd
http://www.springframework.org/schema/security
http://www.springframework.org/schema/security/spring-security-5.4.xsd">
<security:http auto-config="true" disable-url-rewriting="true"
use-expressions="true">
<security:form-login login-page="/signin"
authentication-failure-url="/signinAjax?error=1" authentication-details-source-ref="customWebAuthenticationDetailsSource" authentication-success-forward-url="/logged"/>
<security:intercept-url pattern="/" access="permitAll" />
<security:intercept-url pattern="/isAutenticated" access="permitAll" />
<security:intercept-url pattern="/resources/images/favicon.png"
access="permitAll" />
<security:intercept-url pattern="/resources/webfonts/**"
access="permitAll" />
<security:intercept-url pattern="/resources/**"
access="permitAll" />
<security:intercept-url pattern="/signin"
access="permitAll" />
<security:intercept-url pattern="/signinAjax"
access="permitAll" />
<security:intercept-url pattern="/userList"
access="isAuthenticated()" />
<security:intercept-url pattern="/imgages/**"
access="permitAll" />
<security:intercept-url pattern="/**"
access="isAuthenticated()" />
</security:http>
<security:global-method-security
secured-annotations="enabled" />
<security:authentication-manager
erase-credentials="true">
<security:authentication-provider
ref="ldapActiveDirectoryAuthProvider" />
</security:authentication-manager>
<bean id="ldapActiveDirectoryAuthProvider"
class="org.springframework.security.ldap.authentication.ad.CustomActiveDirectoryLdapAuthenticationProvider">
<constructor-arg value="XXXX" />
<constructor-arg value="ldap://XXX:389" />
<property name="convertSubErrorCodesToExceptions" value="true" />
<property name="searchFilter"
value="(&(objectClass=user)(sAMAccountName={0}))" />
<property name="useAuthenticationRequestCredentials" value="true" />
<property name="userDetailsContextMapper" ref="tdrUserDetailsContextMapper" />
</bean>
<bean id="tdrUserDetailsContextMapper"
class="it.xxx.account.CustomUserDetailsContextMapper" />
<bean id="customWebAuthenticationDetailsSource"
class="it.xxx.config.security.CustomWebAuthenticationDetailsSource"/>
</beans>
That function correctly to this Java Based Configuration
#Configuration
#EnableWebSecurity
//#EnableGlobalMethodSecurity(securedEnabled=true)
//#ImportResource(value = "classpath:spring-security-context.xml")
public class SecurityConfig extends WebSecurityConfigurerAdapter {
#Bean
public CustomWebAuthenticationDetailsSource customWebAuthenticationDetailsSource() {
return new CustomWebAuthenticationDetailsSource();
}
#Override
protected void configure(HttpSecurity http) throws Exception {
http.authorizeRequests().antMatchers("/").permitAll()
.antMatchers("/isAutenticated").permitAll()
.antMatchers("/resources/**").permitAll()
.antMatchers("/signin").permitAll()
.antMatchers("/signinAjax").permitAll()
.antMatchers("/userList").permitAll()
.antMatchers("/images/**").permitAll()
.anyRequest().authenticated()
.and()
.formLogin()
.loginPage("/signin")
.authenticationDetailsSource(customWebAuthenticationDetailsSource())
.successForwardUrl("/logged")
.failureForwardUrl("/signinAjax?error=1");
}
#Bean
public CustomActiveDirectoryLdapAuthenticationProvider ldapActiveDirectoryAuthProvider() {
CustomActiveDirectoryLdapAuthenticationProvider provider = new CustomActiveDirectoryLdapAuthenticationProvider("xxx.local","ldap://xxx:389");
provider.setConvertSubErrorCodesToExceptions(true);
provider.setSearchFilter("(&(objectClass=user)(sAMAccountName={0}))");
provider.setUseAuthenticationRequestCredentials(true);
provider.setUserDetailsContextMapper(tdrUserDetailsContextMapper());
return provider;
}
#Bean
public LoggerListener loggerListener() {
return new LoggerListener();
}
#Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.eraseCredentials(true);
auth.authenticationProvider(ldapActiveDirectoryAuthProvider());
}
#Bean
public CustomUserDetailsContextMapper tdrUserDetailsContextMapper() {
return new CustomUserDetailsContextMapper();
}
}
on compile and runnung of tomcat no error but is impossible to make the loggin and having this error
org.springframework.security.access.event.LoggerListener.onAuthorizationFailureEvent Security authorization failed due to: org.springframework.security.access.AccessDeniedException: Access is denied; authenticated principal: AnonymousAuthenticationToken [Principal=anonymousUser, Credentials=[PROTECTED], Authenticated=true, Details=WebAuthenticationDetails [RemoteIpAddress=0:0:0:0:0:0:0:1, SessionId=19C02E6245BF011635B6ADC374ED4EA4], Granted Authorities=[ROLE_ANONYMOUS]]; secure object: filter invocation [POST /login]; configuration attributes: [authenticated]
I don't know what is missing.
http.csrf().disable()
.authorizeRequests()
.antMatchers("/index","/images/**","/showSignUpForm","/login","/userSignUp",
"/page/**","/sort/**","/sortWithPage/**","/search/**").permitAll()
.anyRequest().authenticated()
.and().formLogin()
.loginPage("/login").defaultSuccessUrl("/index").permitAll()
.and()
.logout()
.invalidateHttpSession(true)
.clearAuthentication(true)
.logoutRequestMatcher(new AntPathRequestMatcher("/logout"))
.logoutSuccessUrl("/login?logout").permitAll();
Try in this way
I found the problems:
Error from xml to java (&)
provider.setSearchFilter("(&(objectClass=user)(sAMAccountName={0}))");
Changed loginPage
#Override
protected void configure(HttpSecurity http) throws Exception {
http.authorizeRequests().antMatchers("/").permitAll()
.antMatchers("/isAutenticated").permitAll()
.antMatchers("/resources/**").permitAll()
.antMatchers("/signin").permitAll()
.antMatchers("/signinAjax").permitAll()
.antMatchers("/userList").permitAll()
.antMatchers("/images/**").permitAll()
.anyRequest().authenticated()
.and()
.formLogin()
.loginPage("/login")
.authenticationDetailsSource(customWebAuthenticationDetailsSource())
.successForwardUrl("/logged")
.failureForwardUrl("/signinAjax?error=1");
}
I don't know how function with xml....
I am making a Spring MVC web application. I have a login page and a dashboard page. Anyone attempting to access the dashboard JSP must be logged in:
Here's my Spring Security config:
#Configuration
#EnableWebSecurity
#EnableGlobalMethodSecurity
#Import({SpringConfiguration.class})
public class SecurityContext extends WebSecurityConfigurerAdapter {
#Autowired
private DataSource dataSource;
// authorizeRequests() -> use-expresions = "true"
#Override
protected void configure(HttpSecurity http) throws Exception {
http
.authorizeRequests()
.antMatchers("/createaccount","/error", "/register", "/login", "/newaccount", "/resources/**").permitAll()
.antMatchers("/**", "/*", "/").authenticated()
.anyRequest().authenticated()
.and()
.formLogin()
.loginPage("/login")
.defaultSuccessUrl("/dashboard")
.loginProcessingUrl("/j_spring_security_check")
.usernameParameter("username")
.passwordParameter("password")
.failureUrl("/login?error=true")
.and()
.logout()
.logoutUrl("/logout")
.logoutSuccessUrl("/login")
.invalidateHttpSession(true)
.and()
.csrf();
// Upon starting the application, it prints the asdfasdf so I know the SecurityContext is loaded
System.out.println("asdfasdf");
}
// Equivalent of jdbc-user-service in XML
#Autowired
public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
auth
.jdbcAuthentication()
.dataSource(dataSource)
.usersByUsernameQuery("SELECT username, password, enabled FROM Users WHERE username=?")
.authoritiesByUsernameQuery("SELECT username, authority FROM authorities where username=?");
}
}
As you can see, I have some endpoints which I permit anyone to access such as /login, /register, but all other URLs require that they be authenticated. When I start the application, if I try go to the dashboard page, I can access it just fine without needing to login which is not what I want.
My issue is that I want people attempting to reach the dashboard to be sent to the login page if they are not logged in/authenticated.
I'm trying to avoid using XML entirely and only use Java to configure my application, would anyone know what I'm doing wrong? I am almost certain it's something wrong with with my SecurityContext.
I might as well include the context XML too of which I'm trying to convert to Java config style
<security:authentication-manager>
<security:jdbc-user-service
data-source-ref="dataSource"
users-by-username-query="select username, password, enabled from Users where username=?"
authorities-by-username-query="select username, authority from Authority where username =? " />
</security:authentication-provider>
</security:authentication-manager>
<security:http use-expressions="true">
<security:intercept-url pattern="/newaccount"
access="permitAll" />
<security:intercept-url pattern="/accountcreated"
access="permitAll" />
<security:intercept-url pattern="/createaccount"
access="permitAll" />
<security:intercept-url pattern="/error"
access="permitAll" />
<security:intercept-url pattern="/resources/**"
access="permitAll" />
<security:intercept-url pattern="/login"
access="permitAll" />
<security:intercept-url pattern="/setemote"
access="isAuthenticated()" />
<security:intercept-url pattern="/**"
access="isAuthenticated()" />
<security:intercept-url pattern="/*"
access="isAuthenticated()" />
<security:form-login login-page="/login"
default-target-url="/" login-processing-url="/j_spring_security_check"
username-parameter="username" password-parameter="password"
authentication-failure-url="/login?error=true" />
<security:csrf />
</security:http>
Good day.
You have to be sure that you have SecurityWebApplicationInitializer, looking like that:
public class SecurityWebApplicationInitializer extends AbstractSecurityWebApplicationInitializer {
public SecurityWebApplicationInitializer() {
super(SecurityContext.class);
}
}
Where SecurityContext - is your class extending WebSecurityConfigurerAdapter.
If you already have it then the problem might be in the lack of roles.
To have roles you might want to implement the config a bit differently, something like that:
.antMatchers("/restricted_area/*")
.access("hasRole('ADMIN')")
.and()
.formLogin()
.loginPage("/login")
.usernameParameter("username")
.passwordParameter("password")
.successHandler(authenticationSuccessHandler)
.permitAll()
.and()
.logout()
.permitAll();
For working with roles and authentication you can extend org.springframework.security.core.userdetails.UserDetailsService having a separate class that would work along with the Spring' authorization/authentication machinery checking the credentials.
As you see I also have authenticationSuccessHandler here. This is actually extended
org.springframework.security.web.authentication.AuthenticationSuccessHandler
What it does is redirecting to specific pages depending on the role: e.g. regular user to user' dashboard, admin to admin' dashboard.
Not sure if this is relevant to your question though, but the implementation is something like that:
#Component("customHandler")
public class CustomAuthenticationHandler implements AuthenticationSuccessHandler {
private static final Logger logger = LoggerFactory.getLogger(CustomAuthenticationHandler.class);
private RedirectStrategy redirectStrategy = new DefaultRedirectStrategy();
#Autowired
private UserService userService;
#Override
public void onAuthenticationSuccess(HttpServletRequest request, HttpServletResponse response,
Authentication authentication) throws IOException {
Object principal = authentication.getPrincipal();
String username = ((UserDetails) principal).getUsername();
userService.updateLastLoginTimeByName(username);
handle(request, response, authentication);
clearAuthenticationAttributes(request);
}
protected void handle(HttpServletRequest request, HttpServletResponse response, Authentication authentication)
throws IOException {
String targetUrl = determineTargetUrl(authentication);
if (response.isCommitted()) {
logger.debug("Response has already been committed. Unable to redirect to " + targetUrl);
return;
}
redirectStrategy.sendRedirect(request, response, targetUrl);
}
/**
* Builds the target URL according to the logic defined in the main class
* Javadoc.
*/
protected String determineTargetUrl(Authentication authentication) {
boolean isAdmin = false;
Collection<? extends GrantedAuthority> authorities = authentication.getAuthorities();
for (GrantedAuthority grantedAuthority : authorities) {
if (grantedAuthority.getAuthority().equals("ROLE_ADMIN")) {
isAdmin = true;
break;
}
}
if (isAdmin) {
return "/restricted_area/";
} else {
throw new IllegalStateException();
}
}
protected void clearAuthenticationAttributes(HttpServletRequest request) {
HttpSession session = request.getSession(false);
if (session == null) {
return;
}
session.removeAttribute(WebAttributes.AUTHENTICATION_EXCEPTION);
}
public void setRedirectStrategy(RedirectStrategy redirectStrategy) {
this.redirectStrategy = redirectStrategy;
}
protected RedirectStrategy getRedirectStrategy() {
return redirectStrategy;
}
}
<bean class="org.springframework.security.web.access.expression.DefaultWebSecurityExpressionHandler"/>
<security:http use-expressions="false" entry-point-ref="loginEntryPoint">
<security:custom-filter ref="customFormLoginFilter" position="FORM_LOGIN_FILTER"/>
<security:logout logout-url="/logout" logout-success-url="/login?logout=true"/>
<security:intercept-url pattern="/appointments/*" access="ROLE_USER"/>
<security:intercept-url pattern="/schedule/*" access="ROLE_FOO"/>
<security:intercept-url pattern="/**" access="ROLE_ANONYMOUS, ROLE_USER"/>
</security:http>
<bean id="customFormLoginFilter" class="com.fetn.security.CustomAuthenticationFilter">
<property name="filterProcessesUrl" value="/login"/>
<property name="authenticationManager" ref="authenticationManager"/>
<property name="usernameParameter" value="custom_username"/>
<property name="passwordParameter" value="custom_password"/>
<property name="authenticationSuccessHandler">
<bean class="org.springframework.security.web.authentication.SavedRequestAwareAuthenticationSuccessHandler">
<property name="defaultTargetUrl" value="/"/>
</bean>
</property>
<property name="authenticationFailureHandler">
<bean class="org.springframework.security.web.authentication.SimpleUrlAuthenticationFailureHandler">
<property name="defaultFailureUrl" value="/login/failure?error=true"/>
</bean>
</property>
</bean>
<bean id="loginEntryPoint" class="org.springframework.security.web.authentication.LoginUrlAuthenticationEntryPoint">
<constructor-arg value="/login"/>
</bean>
<security:authentication-manager alias="authenticationManager">
<security:authentication-provider ref="customAuthenticationProvider"/>
</security:authentication-manager>
I wrote belowJava Config Code but for logout and .antMatchers("/appointments/").access("hasRole('USER')") and antMatchers("/schedule/").access("hasRole('ADMIN')")
URL always go to /login/failure?error=true
what will be the appropriate java cofig code .Please Help.....
#Configuration
#EnableWebSecurity
public class SecurityConfiguration extends WebSecurityConfigurerAdapter{
#Autowired
private AutoUserRepository autoUserRepository;
#Autowired
private CustomAuthenticationProvider customAuthenticationProvider;
#Autowired
public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
auth.authenticationProvider(customAuthenticationProvider);
}
#Override
protected void configure(HttpSecurity http) throws Exception {
http.authorizeRequests()
.antMatchers("/appointments/*").access("hasRole('USER')").
antMatchers("/schedule/*").access("hasRole('ADMIN')").and().exceptionHandling().authenticationEntryPoint(loginEntryPoint()).and().addFilterBefore(customFormLoginFilter(), UsernamePasswordAuthenticationFilter.class);
http.logout().logoutUrl("/logout")
.logoutSuccessUrl("/login?logout=true");
}
#Override
public void configure(WebSecurity web) throws Exception {
web.ignoring().antMatchers("/resources/**");
}
#Bean
public DefaultWebSecurityExpressionHandler defaultWebSecurityExpressionHandler(){
return new DefaultWebSecurityExpressionHandler();
}
#Bean
public LoginUrlAuthenticationEntryPoint loginEntryPoint(){
LoginUrlAuthenticationEntryPoint ent=new LoginUrlAuthenticationEntryPoint("/login");
return ent;
}
#Bean
public CustomAuthenticationFilter customFormLoginFilter() throws Exception{
CustomAuthenticationFilter filter=new CustomAuthenticationFilter();
//setting up super class property AbstractAuthenticationProcessingFilter
filter.setFilterProcessesUrl("/login");//login url
filter.setAuthenticationManager(authenticationManagerBean());
filter.setUsernameParameter("custom_username");
filter.setPasswordParameter("custom_username");
filter.setAuthenticationSuccessHandler(savedRequestAwareAuthenticationSuccessHandler());
filter.setAuthenticationFailureHandler(simpleUrlAuthenticationFailureHandler());
return filter;
}
#Bean
public SavedRequestAwareAuthenticationSuccessHandler savedRequestAwareAuthenticationSuccessHandler(){
SavedRequestAwareAuthenticationSuccessHandler surl=new SavedRequestAwareAuthenticationSuccessHandler();
surl.setDefaultTargetUrl("/");//url after seuuces login
return surl;
}
#Bean
SimpleUrlAuthenticationFailureHandler simpleUrlAuthenticationFailureHandler(){
SimpleUrlAuthenticationFailureHandler faillure=new SimpleUrlAuthenticationFailureHandler();
faillure.setDefaultFailureUrl("/login/failure?error=true");
return faillure;
}
#Bean
#Override
public AuthenticationManager authenticationManagerBean() throws Exception {
return super.authenticationManagerBean();
}
}
Could it be that you have to add .and() between the various antMatchers? Also you are using two http.* calls i think it can be done with one. See code below from this page.
protected void configure(HttpSecurity http) throws Exception {
http
.authorizeRequests()
.antMatchers("/", "/home").permitAll()
.anyRequest().authenticated()
.and()
.formLogin()
.loginPage("/login")
.permitAll()
.and()
.logout()
.permitAll();
}
I am new to Spring Security and I am working on a login, logout, and session timeout feature. I have configured my code by referring to this document. My code looks below:
#Override
protected void configure(HttpSecurity http) throws Exception {
http.authorizeRequests().antMatchers("/admin/**")
.access("hasRole('ROLE_USER')").and().formLogin()
.loginPage("/login").failureUrl("/login?error")
.usernameParameter("username")
.passwordParameter("password")
.and().logout().logoutSuccessUrl("/login?logout").and().csrf();
http.sessionManagement().maximumSessions(1).expiredUrl("/login?expired");
}
Override the class AbstractSecurityWebApplicationInitializer
import org.springframework.security.web.context.AbstractSecurityWebApplicationInitializer;
public class SpringSecurityInitializer extends AbstractSecurityWebApplicationInitializer {
#Override
public boolean enableHttpSessionEventPublisher() {
return true;
}
}
I need clarification on whether I am doing it right, if it looks good, then where I need to setup the session timeout. I am doing it fully based on annotation.
If you are using JavaConfig and do not want to use XML you can create a HttpSessionListener and use getSession().setMaxInactiveInterval(), then in the Initializer add the listener in onStartup():
public class SessionListener implements HttpSessionListener {
#Override
public void sessionCreated(HttpSessionEvent event) {
System.out.println("session created");
event.getSession().setMaxInactiveInterval(15);
}
#Override
public void sessionDestroyed(HttpSessionEvent event) {
System.out.println("session destroyed");
}
}
Then in the Initializer:
#Override
public void onStartup(ServletContext servletContext) throws ServletException {
super.onStartup(servletContext);
servletContext.addListener(new SessionListener());
}
I was able to solve above issue by adding below config in web.xml only. any better way will be accepted.
<session-config>
<session-timeout>20</session-timeout>
</session-config>
When using application.properties set property server.session.timeout= value is in seconds.
Different ways to configure session timeout time(maxInactiveInterval) in spring security.
1. By addinng session config in web.xml(from raju vaishnav's answer)
2. By creating implementation of HttpSessionListener and adding it to servlet context.(from munilvc's answer)
3. By registering your custom AuthenticationSuccessHandler in spring security configuration, and setting session maximum inactive interval in onAuthenticationSuccess method.
This implementation has advantages
On login success, You can set different value of maxInactiveInterval for different roles/users.
On login success, you can set user object in session, hence user object can be accessed in any controller from session.
Disadvantage: You can not set session timeout for ANONYMOUS user(Un-authenticated user)
Create AuthenticationSuccessHandler Handler
public class MyAuthenticationSuccessHandler implements AuthenticationSuccessHandler
{
public void onAuthenticationSuccess(HttpServletRequest request, HttpServletResponse response, Authentication authentication)
throws IOException
{
Set<String> roles = AuthorityUtils.authorityListToSet(authentication.getAuthorities());
if (roles.contains("ROLE_ADMIN"))
{
request.getSession(false).setMaxInactiveInterval(60);
}
else
{
request.getSession(false).setMaxInactiveInterval(120);
}
//Your login success url goes here, currently login success url="/"
response.sendRedirect(request.getContextPath());
}
}
Register success handler
In Java Config way
#Override
protected void configure(final HttpSecurity http) throws Exception
{
http
.authorizeRequests()
.antMatchers("/resources/**", "/login"").permitAll()
.antMatchers("/app/admin/*").hasRole("ADMIN")
.antMatchers("/app/user/*", "/").hasAnyRole("ADMIN", "USER")
.and().exceptionHandling().accessDeniedPage("/403")
.and().formLogin()
.loginPage("/login").usernameParameter("userName")
.passwordParameter("password")
.successHandler(new MyAuthenticationSuccessHandler())
.failureUrl("/login?error=true")
.and().logout()
.logoutSuccessHandler(new CustomLogoutSuccessHandler())
.invalidateHttpSession(true)
.and().csrf().disable();
http.sessionManagement().maximumSessions(1).expiredUrl("/login?expired=true");
}
In xml config way
<http auto-config="true" use-expressions="true" create-session="ifRequired">
<csrf disabled="true"/>
<intercept-url pattern="/resources/**" access="permitAll" />
<intercept-url pattern="/login" access="permitAll" />
<intercept-url pattern="/app/admin/*" access="hasRole('ROLE_ADMIN')" />
<intercept-url pattern="/" access="hasAnyRole('ROLE_USER', 'ROLE_ADMIN')" />
<intercept-url pattern="/app/user/*" access="hasAnyRole('ROLE_USER', 'ROLE_ADMIN')" />
<access-denied-handler error-page="/403" />
<form-login
login-page="/login"
authentication-success-handler-ref="authenticationSuccessHandler"
authentication-failure-url="/login?error=true"
username-parameter="userName"
password-parameter="password" />
<logout invalidate-session="false" success-handler-ref="customLogoutSuccessHandler"/>
<session-management invalid-session-url="/login?expired=true">
<concurrency-control max-sessions="1" />
</session-management>
</http>
<beans:bean id="authenticationSuccessHandler" class="com.pvn.mvctiles.configuration.MyAuthenticationSuccessHandler" />
Working code is available in my github repository
Working code is available in two forms
1. XML config way of implementation
2. JAVA config way of implementation
If you want to have automatic logout feature and timer which displays when session is about to expire, if user is filling form but not submitted then user can extend session by clicking on keep session alive button.
If you want to implement auto logout refer stack overflow answer on auto logout on session timeout. Hope this will help.
In your application properties use
server.servlet.session.timeout=1m (If a duration suffix is not specified, seconds will be used.)
By default it is 30 minutes.
I handled it inside subclass of UsernamePasswordAuthenticationFilter
You can get username by -
obtainUsername(request);
and apply user checks and set time out accordingly, like-
if(username.equalsIgnoreCase("komal-singh-sisodiya#xyz.com"))
{
logger.debug("setting timeout 15 min");
request.getSession(false).setMaxInactiveInterval(15*60);
}
Add the below in application.proprites
server.servlet.session.timeout=
this will work:
#EnableJdbcHttpSession(maxInactiveIntervalInSeconds = 84600)
I am using java config for spring security and I am trying to replace this code with no luck
<security:custom-filter ref="authenticationTokenProcessingFilter" position="FORM_LOGIN_FILTER" />
cant find any info about how to use the position in java config
Update i am trying to replace this code by java config but with no luck
<security:http
realm="Protected API"
use-expressions="true"
auto-config="false"
create-session="stateless"
entry-point-ref="unauthorizedEntryPoint"
authentication-manager-ref="authenticationManager">
<security:custom-filter ref="authenticationTokenProcessingFilter" position="FORM_LOGIN_FILTER" />
<security:intercept-url pattern="/rest/user/authenticate" access="permitAll" />
<security:intercept-url method="GET" pattern="/rest/news/**" access="hasRole('user')" />
<security:intercept-url method="PUT" pattern="/rest/news/**" access="hasRole('admin')" />
<security:intercept-url method="POST" pattern="/rest/news/**" access="hasRole('admin')" />
<security:intercept-url method="DELETE" pattern="/rest/news/**" access="hasRole('admin')" />
</security:http>
<bean id="unauthorizedEntryPoint" class="net.dontdrinkandroot.example.angularrestspringsecurity.rest.UnauthorizedEntryPoint" />
<bean class="net.dontdrinkandroot.example.angularrestspringsecurity.rest.AuthenticationTokenProcessingFilter" id="authenticationTokenProcessingFilter">
<constructor-arg ref="userDao" />
</bean>
and this is my AuthenticationTokenProcessingFilter
public class AuthenticationTokenProcessingFilter extends UsernamePasswordAuthenticationFilter
{
private final UserDetailsService userService;
public AuthenticationTokenProcessingFilter(UserDetailsService userService)
{
this.userService = userService;
}
#Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException,
ServletException
{
HttpServletRequest httpRequest = this.getAsHttpRequest(request);
String authToken = this.extractAuthTokenFromRequest(httpRequest);
String userName = TokenUtils.getUserNameFromToken(authToken);
if (userName != null) {
UserDetails userDetails = this.userService.loadUserByUsername(userName);
if (TokenUtils.validateToken(authToken, userDetails)) {
UsernamePasswordAuthenticationToken authentication =
new UsernamePasswordAuthenticationToken(userDetails, null, userDetails.getAuthorities());
authentication.setDetails(new WebAuthenticationDetailsSource().buildDetails(httpRequest));
SecurityContextHolder.getContext().setAuthentication(authentication);
}
}
chain.doFilter(request, response);
}
private HttpServletRequest getAsHttpRequest(ServletRequest request)
{
if (!(request instanceof HttpServletRequest)) {
throw new RuntimeException("Expecting an HTTP request");
}
return (HttpServletRequest) request;
}
private String extractAuthTokenFromRequest(HttpServletRequest httpRequest)
{
/* Get token from header */
String authToken = httpRequest.getHeader("X-Auth-Token");
/* If token not found get it from request parameter */
if (authToken == null) {
authToken = httpRequest.getParameter("token");
}
return authToken;
}
Hope this is clearer
Here are the filter classes in the order of execution and with the addFilter method of the HttpSecurity class you add your own filters:
#Override
public void configure(HttpSecurity http) throws Exception {
http.addFilter(new AuthenticationTokenProcessingFilter());
...
You have to either extend or provide an instance of the defined Spring filters. The order is based on the class or superclass so you don't have to add the position:
JavaDoc