Enabling spring
security in your spring application
In your roo application you will have to run following
command which will generate all the security related pages and needed
configuration for you.
Roo> Security
Setup
The above command will create
everything needed for spring security , now go to your “applicationContext-security.xml”
file under your project’s
resources/META-INF/spring folder.
If you want Spring to show login screen whenever your user
want’s to access any URL then include following interceptors in your applicationContext-security.xml file under http tage
<http auto-config="true"
use-expressions="true">
<!--
<form-login />
-->
<form-login
login-processing-url="/resources/j_spring_security_check"
login-page="/login" authentication-failure-url="/login?login_error=t"
/>
<logout logout-url="/resources/j_spring_security_logout"
/>
<!--
Configure these elements to secure URIs in your application -->
<intercept-url pattern="/login**" access="permitAll"
/>
<intercept-url pattern="/**" access="isAuthenticated()"
/>
</http>
Note the bold lines in
above code , the first line will tell spring to allow access to /login URL only
, while the second line will restrict all the other URLS in your application
and will allow access only if the user is authenticated and has required roles.
Note that if you don’t want to have your own login page and
want spring to handle security (login page based) then comment the below line
<form-login
login-processing-url="/resources/j_spring_security_check"
login-page="/login" authentication-failure-url="/login?login_error=t"
/>
And uncomment below line
<!--
<form-login />
-->
Try to run your spring application now and spring will still
show you a login page and notice that you don’t need to create a login.jsp page
in this case.
Customizing
Spring Security
We can even customize the spring security to use our own class where we
can put the code to authenticate the user against our database , please follow
the steps mentioned below
Writing
custom AuthenticationProvider
We will write a custom Authentication provider by extending a classcalled
AbstractUserDetailsAuthenticationProvider, which works with username/password
like authentication. The classes that extend AbstractUserDetailsAuthenticationProvider
have to provide implementation for its two abstract methods:
·
additionalAuthenticationChecks and
·
retrieveUser.
The provider calls the retrieveUser method to authenticate user , this is
where you can authenticate the user in your application against your own
database , below is the class
package mypackage;
import
org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import
org.springframework.security.authentication.dao.AbstractUserDetailsAuthenticationProvider;
import org.springframework.security.core.AuthenticationException;
import
org.springframework.security.core.userdetails.UserDetails;
public class
DrillingBestPracticesAuthenticationProvider extends
AbstractUserDetailsAuthenticationProvider
{
@Override
protected void
additionalAuthenticationChecks(UserDetails arg0,
UsernamePasswordAuthenticationToken
arg1)
throws
AuthenticationException {
// TODO Auto-generated
method stub
}
@Override
protected UserDetails
retrieveUser(String username,
UsernamePasswordAuthenticationToken
authentication)
throws
AuthenticationException {
String
password = (String) authentication.getCredentials();
if (!StringUtils.hasText(password))
{
throw new
BadCredentialsException("Please enter password");
}
List<GrantedAuthority>
authorities = new ArrayList<GrantedAuthority>();
try
{
//TODO here I should be
trying to get the database connection using user name and password if
connection successfully made then it means user is authenticated to use our
system
}
catch
(EmptyResultDataAccessException e)
{
throw new
BadCredentialsException("Invalid username or password");
}
catch
(EntityNotFoundException e) {
throw new
BadCredentialsException("Invalid user");
}
catch
(NonUniqueResultException e) {
throw new
BadCredentialsException("Non-unique user, contact administrator");
}
return new User(username,
password,
true, // enabled
true, // account not
expired
true, // credentials
not expired
true, // account not
locked
authorities);
}
}
And you will have to add AuthenticationManager in your applicationContext-security.xml file as below
<beans:bean name="drillingBestPracticesAuthenticationProvider" class="mypackage.DrillingBestPracticesAuthenticationProvider">
</beans:bean>
<authentication-manager alias="authenticationManager">
<authentication-provider ref="drillingBestPracticesAuthenticationProvider"></authentication-provider>
</authentication-manager>
Now once the user has been authenticated and User object
being returned by the retrieveUser method , Spring will allow you to get user
detail from anywhere in your application using any of the three approaches
mentioned in the blogpost at following link
I am copy pasting the three methods mentioned in above blog
First Method
Authentication auth =
SecurityContextHolder.getContext().getAuthentication();
String name = auth.getName(); //get logged in
username
Second Method
User user = (User)SecurityContextHolder.getContext().getAuthentication().getPrincipal();
String name = user.getUsername(); //get logged in username
Third Method
@RequestMapping(value="/login", method = RequestMethod.GET)
public String printWelcome(ModelMap model, Principal principal ) {
String name = principal.getName(); //get logged in username
model.addAttribute("username", name);
return "hello";
}
If you want to store user password in SecurityContext then you will have to define a property in the configuration of your custom AuthenticationManager Like below
ReplyDeleteerase-credentials="false"
and after successfull login you can get the user name password for a user as mentioned below
Authentication auth = SecurityContextHolder.getContext().getAuthentication();
//**Get Logedin User's user name
String username = auth.getName(); //get logged in username
//**Get Login User's password
String password = (String)auth.getCredentials();
UserCredentialsDataSourceAdapter userAdapter=new UserCredentialsDataSourceAdapter();
userAdapter.setCredentialsForCurrentThread(username, password);
Basit bhai , spring secrity ko chorain , trip planing karain :)
ReplyDelete