Reputation: 1817
I have successfully created a Spring RESTful webservice with different APIs. Now I should protect them from unauthorized access. I followed http://www.beingjavaguys.com/2014/10/spring-security-oauth2-integration.html and the login logic is entirely different from mine. Can someone help me to move on?
Fetch user login request
@RequestMapping(value = "/login", method = RequestMethod.POST)
@ResponseBody
@ResponseStatus(HttpStatus.OK)
public UserResponse login(@RequestBody final UserLoginRequest userRequest) throws ServletException, IOException {
UserResponse userResponse = new UserResponse();
try {
userResponse = accessService.login(userRequest);
} catch (SQLException e) {
e.printStackTrace();
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
return userResponse;
}
Process user login request
@Transactional
public UserResponse login(UserLoginRequest userRequest) throws SQLException,
ClassNotFoundException, IOException {
UserResponse userResponse = new UserResponse();
int status = 0;
//boolean isExist = loginDao.isUserExist(userRequest.getUsername(), userRequest.getPassword());
User user = loginDao.getUser(userRequest.getEmailID());
if (user != null) {
if (userRequest.getPassword().equals(user.getPassword())) {//Case sensitive password and added to check status
//User exist
if (user.getStatus().equals("1")) {
//Device token check
loginDao.isDeviceTokenExists(userRequest, user.getProfileId());
status = 2;
} else {
status = 3;
}
} else {
status = 4;
}
} else {
status = 1;
}
if (status == 1) {
userResponse.setCode(WeekenterConstants.USER_EMAIL_EXIST_CODE);
userResponse.setMessage("User does not exists.Please Register.");
} else if (status == 2) {
userResponse.setCode(WeekenterConstants.SUCCESS_CODE);
userResponse.setMessage("User login success");
userResponse.setId(user.getProfileId());
} else if (status == 3) {
userResponse.setCode(WeekenterConstants.FAILURE_CODE);
userResponse.setMessage("Your Account is blocked. Please contact Weekenter administrator.");
userResponse.setId(user.getProfileId());
} else if (status == 4) {
userResponse.setCode(WeekenterConstants.FAILURE_CODE);
userResponse.setMessage("Password is wrong.");
userResponse.setId(user.getProfileId());
}
return userResponse;
}
I have API's for fetch countries, userlist etc. Those services should only give data to the Android client once the user is valid. I know the authentication will be processed by using access token. How could I do it in a standard way?
Upvotes: 5
Views: 156
Reputation: 10549
You can follow the mentioned tutorial itself by changing the login logic in your service.define a custom authentication service in your
spring-security.xml
.Typically, a simple Spring Security enabled application would use a simple user service as the authentication source:
<!--Custom User details service which is provide the user data-->
<bean id="customUserDetailsService"
class="com.yourpackage.CustomUserDetailsService" />
<authentication-manager alias="authenticationManager">
<authentication-provider user-service-ref="customUserDetailsService" />
</authentication-manager>
Your
customUserDetailsService
should implementUserDetailsService
available inorg.springframework.security.core.userdetails.UserDetailsService
import com.weekenter.www.dao.LoginDao;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.userdetails.User;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
@Service
@Transactional(readOnly = true)
public class CustomUserDetailsService implements UserDetailsService {
@Autowired
private LoginDao loginDao;
public UserDetails loadUserByUsername(String login)
throws UsernameNotFoundException {
boolean enabled = true;
boolean accountNonExpired = true;
boolean credentialsNonExpired = true;
boolean accountNonLocked = true;
com.weekenter.www.entity.User user = null;
try {
user = loginDao.getUser(login);//login variable contain your requested username
if (user != null) {
if (user.getStatus().equals("1")) {
enabled = false;
}
} else {
throw new UsernameNotFoundException(login + " Not found !");
}
} catch (Exception ex) {
try {
throw new Exception(ex.getMessage());
} catch (Exception ex1) {
}
}
<!-- Password comparison will happen here -->
return new User(
user.getEmail(),
user.getPassword(),
enabled,
accountNonExpired,
credentialsNonExpired,
accountNonLocked,
getAuthorities()
);
}
public Collection<? extends GrantedAuthority> getAuthorities() {
List<GrantedAuthority> authList = getGrantedAuthorities(getRoles());
return authList;
}
public List<String> getRoles() {
List<String> roles = new ArrayList<String>();
roles.add("ROLE_APP");
return roles;
}
public static List<GrantedAuthority> getGrantedAuthorities(List<String> roles) {
List<GrantedAuthority> authorities = new ArrayList<GrantedAuthority>();
for (String role : roles) {
authorities.add(new SimpleGrantedAuthority(role));
}
return authorities;
}
}
And finally in
spring-security.xml
you can filter protected URL's like below
<!-- This is where we tells spring security what URL should be protected
and what roles have access to them -->
<http pattern="/api/**" create-session="never"
entry-point-ref="oauthAuthenticationEntryPoint"
access-decision-manager-ref="accessDecisionManager"
xmlns="http://www.springframework.org/schema/security">
<anonymous enabled="false" />
<intercept-url pattern="/api/**" access="ROLE_APP" />
<custom-filter ref="resourceServerFilter" before="PRE_AUTH_FILTER" />
<access-denied-handler ref="oauthAccessDeniedHandler" />
</http>
Upvotes: 0
Reputation: 131
I think you need to have a separate process that will authorize a device for use in your application.
I have worked on an application in which tablets are registered for using an app. The tablet ID is saved in a simple text file that is accessible to the Apache server. Then all REST requests have a special header X_DEVICEID which contains the device ID, and a PHP script used by Apache checks for this ID in the file, and will only give a response if the ID is for a registered device.
The file of allowed device IDs acts as a sort of firewall to block unregistered devices.
Upvotes: 1