I am working with jhipster. I need to create a new table for auditing my database changes and link it with the default jhi_persistenet_audit_event table generated by the Jhipster. How I can get the current logged user record from the jhi_persistenet_audit_event table to link that id to my new table?
Solution 1: Principal principal
#RequestMapping(value = {"/", ""})
public String start(Principal principal, Model model) {
String currentUser = principal.getName();
return currentUser;
}
Solution 2: Authentication authentication
#RequestMapping(value = {"/", ""})
public String currentUserName(Authentication authentication) {
return authentication.getName();
}
Solution 3: SecurityContextHolder
Object principal = SecurityContextHolder.getContext().getAuthentication().getPrincipal();
if (principal instanceof UserDetails) {
String username = ((UserDetails)principal).getUsername();
} else {
String username = principal.toString();
}
Details 1 Details 2
Related
I am hashing my user passwords while saving the entities to the database.
While doing that, I'm unable to update the username, without hashing the password again.
I wrote the test for it, which fails.
#Test
#DisplayName("Update")
public void testForUpdate() {
final User user = new User("UserForUpdate", "UpdatedUser123");
this.userService.save(user);
User found = this.userService.findOneByUsernameAndPassword(user.getUsername(), user.getPassword());
assertTrue(found.getId() != null, "Found real user");
this.userService.save(found);
final User asserted = this.userService.findOneByUsernameAndPassword(found.getUsername(), user.getPassword());
assertTrue(asserted != null, "Updated user found");
assertTrue(user.getId() == asserted.getId(), "User ID is persisted");
}
The save method from the UserService looks like this:
#Override
public User save(User newUser) {
newUser.setPassword(passwordEncoder.encode(newUser.getPassword()));
return repository.save(newUser);
}
Am I doing something wrong saving it like this?
How should I proceed, to implement the CRUD Update correctly?
Thanks for any pointers
Do not modify the password when you store the user. Instead encode the password when you modify it.
public class UserSevice {
...
public changePassword(User user, String plainPassword) {
user.setPassword(passwordEncoder.encode(plainPassword));
}
}
I have User class like this :
#Data
#Entity
public class User {
#Id #GeneratedValue Long userID;
String eMail;
String passwordHash;
}
And I have data like this :
[{"userID":1,"passwordHash":"asdasd","email":"admin#admin.com"},
{"userID":2,"passwordHash":"12345","email":"admin1asdasd#admin.com"}]
I have two method , one - to get single user :
// Single item
#GetMapping("/user/{id}")
User one(#PathVariable Long id) {
return repository.findById(id)
.orElseThrow(() -> new UserNotFoundException(id));
}
Other method to retrieve all user :
// Aggregate root
#GetMapping("/user")
List<User> all() {
return repository.findAll();
}
Now how can I match password ? What will be the efficient way ?
You may want to consider this kind of an aproach: in general, you should save hashed password in the database and check passwords using hashed values. Bcrypt is a good option for hashing and it can be easily integrated with Spring.
As explained in the link above you can define a password encoder service:
#Bean
public PasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}
and you can use it like this:
#Autowired
private PasswordEncoder passwordEncoder;
//...
User user = new User();
user.setFirstName(accountDto.getFirstName());
user.setLastName(accountDto.getLastName());
user.setPassword(passwordEncoder.encode(accountDto.getPassword()));
user.setEmail(accountDto.getEmail());
user.setRole(new Role(Integer.valueOf(1), user));
repository.save(user);
where accountDto contains the password in clear-text.
Now you can expose a dedicated login method that compares hashed values, something along these lines:
void login(String username, char[] password) throws Exception {
User user = userRepository.findByUsername(username);
if (user != null) {
String encodedPassword = user.getPassword();
if(passwordEncoder.matches(String.valueOf(password), encodedPassword)) {
return;
}
}
throw new Exception("User cannot be authenticated");
}
I'm currently using db (mysql) to store my sessions with spring. It is generating new session id for each user but it is replacing session id's of previously who are logged. Please give some suggestions to overcome this problem.
The following the service which is I am calling from controller for each request
image1
image2
public class MultiLoginServiceImpl
{
public static String createMultiLogin(HttpServletRequest httpRequest)
{
String alias = httpRequest.getParameter("_s");
System.err.println("alias"+alias);
#SuppressWarnings("unchecked")
SessionRepository<Session> sessionRepository =(SessionRepository<Session>) httpRequest.getAttribute(SessionRepository.class.getName());
Map<String, String> sessionIds = sessionManager.getSessionIds(httpRequest);
System.out.println(sessionIds);
for(Map.Entry<String, String> entry : sessionManager.getSessionIds(httpRequest).entrySet()) {
String aliasId = entry.getKey();
String sessionId = entry.getValue();
HttpSession httpSession = httpRequest.getSession(false);
Session storedSession = sessionRepository.getSession(sessionId);
if(storedSession.getAttribute("userEmailId")!= null)
{
httpSession.setAttribute("userEmailId", storedSession.getAttribute("userEmailId"));
}
System.out.println("mapids"+aliasId +" : "+sessionId);
}
String addAlias = alias== null ? newSessionAlias1: requestedSessionAlias1;
/*if(alias == null || "".equals(alias.trim()))
{
alias = sessionManager.getNewSessionAlias(httpRequest);
}*/
httpRequest.setAttribute("alias",addAlias);
//SecurityContext context = (SecurityContext) httpSession.getAttribute(HttpSessionSecurityContextRepository.SPRING_SECURITY_CONTEXT_KEY);
//System.out.println(context.toString());
String addAccountUrl = sessionManager.encodeURL(httpRequest.getContextPath(), addAlias);
System.out.println("addalias"+addAlias);
return addAccountUrl ;
}
}
my task is to provide role based menu to the users.....this is the first time i am practically working on MVC3 so expecting your help....
I am geing the roles from the database...
so i have different menus like this [Home],[About],[Projects],[SetUP],[Resources] and like this what i wan to do is when an user wiht role [admin] logs in i have to provide him with [Home],[About],[SetUP] menus only,how can i do this can any one help me in doing this briefly.....
this is what i did till now
how will i get the role name from role id in the tables....i had created a login where i dnt use role based now how can i provide role based login
this is my LoginModel Class
public class LoginModel
{
[Required]
[Display(Name = "User name")]
public string UserName { get; set; }
[Required]
[DataType(DataType.Password)]
[Display(Name = "Password")]
public string Password { get; set; }
[Display(Name = "Remember me?")]
public bool RememberMe { get; set; }
public bool IsValid(string _username, string _pwd)
{
SqlConnection cn = new SqlConnection("Data Source=LMIT-0039;Initial Catalog=BugTracker;Integrated Security=True");
cn.Open();
SqlCommand cmd = new SqlCommand("GetRoleName", cn);
cmd.CommandType = CommandType.StoredProcedure;
cmd.Parameters.Add("#UserName ", SqlDbType.VarChar).Value = _username;
cmd.Parameters.Add("#Password", SqlDbType.VarChar).Value = _pwd;
Object TypeUser = cmd.ExecuteScalar();
cn.Close();
if (TypeUser != null)
{
if (TypeUser.ToString() == "Admin")
return true;
else if (TypeUser.ToString() == "Developer")
return true;
else if (TypeUser.ToString() == "QA")
return true;
else
return false;
}
return true;
}
can any one help me in doing this please....
If you use the built in Forms authentication you can access users roles like this:
string userRole = Roles.GetRolesForUser(User.Identity.Name).FirstOrDefault();
I used the FirstOrDefault because a user could have more than one role. From here you can use a switch statement to return the related view. Also if you want to hide items (like menu items in the global layout,) you can do this:
#if(Roles.GetRolesForUser(User.Identity.Name).FirstOrDefault() == "TheRoleYouWant")
{
...
}
Also you can add an Authorize attribute to a function in a controller (or the entire controller) that will only allow users with this role to access it. Like this:
[Authorize(Roles = "Admin, Role2, Role3")]
public ActionResult Index()
{
return View();
}
Note that you can add more than one role, they just need to be comma separated like above.
There are a lot of other options, like IsUserInRole("Admin"), take a look at Implementing a Role Provider.
I'm new at MVC and can't get this to work. I basically have a Users class, a UserRepository, and a IUser interface.
This is my code:
public class Users
{
public string UserName { get; set; }
public string Department { get; set; }
public string UserType { get; set; }
}
public class UsersRepository : TimeAttendanceMVC.Models.IUsers
{
public Users Return_UserName_Dept()
{
Users U = new Users();
List<Users> LoggedInUser = new List<Users>();
U.UserName = "TestUser";
U.Department = "Finance";
U.UserType = "Administrator";
LoggedInUser.Add(U);
//string json = JsonConvert.SerializeObject(LoggedInUser, Formatting.Indented);
//return json;
return Json(LoggedInUser.ToArray(), JsonRequestBehavior.AllowGet);
}
}
namespace TimeAttendanceMVC.Models
{
public class IUsers
{
List<Users> Return_UserName_Dept();
}
}
There are a few errors that I get. In UsersRepository.cs where i'm returning Json, the error says that "The name Json does not exist in the current context". The error from IUsers.cs is that "Return_UserName_Dept() must declare a body because it is not marked abstract...".
Can anybody please help me with this. I just don't know how this is supposed to work and i'm trying to learn MVC by working on this application. It's actually the FullCalendar application found here - link to FullCalendar. I'm trying to turn it into an MVC application.
EDIT:
Maybe I need to do this:
public JsonResult Return_UserName_Dept()
instead of public Users Return_UserName_Dept()
You should be doing this on your controller in some method which returns a json action (jsonresult). The repository should be returning your data only and all the operations you need to do, whether you're converting data to json or any other logic should happen at the controller or at some helper class which would be called by the controller..
Edit:
In order to have a method which returns a JsonResult, you need to have a reference to System.Web.Mvc.ActionResult and since the repository is usually at the model, you won't have this reference.. another thing is that you might be breaking your design the logic should be available at the controller for what you want
Edit 2:
The code below is from an old post you can see here. Note how the action PopulateDetails gets the user object from the repository and that's all the repository does.. the actual logic is happening inside this method, such as populate the rest of the UserModel class, and then it returns the JsonResult:
public JsonResult PopulateDetails(UserModel model)
{
UserResultModel userResultModel = new UserResultModel();
if (String.IsNullOrEmpty(model.UserId))
{
userResultModel.Message = "UserId can not be blank";
return Json(userResultModel);
}
User user = _userRepository.GetUser(model.UserId);
if (user == null)
{
userResultModel.Message = String.Format("No UserId found for {0}", model.UserId);
return Json(userResultModel);
}
userResultModel.LastName = user.LastName;
userResultModel.FirstName = user.FirstName;
userResultModel.Message = String.Empty; //success message is empty in this case
return Json(userResultModel);
}