I am new in spring security and I have several question on this topic.
Can I use regular html files or I need to create jsp file for the login page ?
and if I don't want to create form but only few fields is it ok ?
This is my HTML in JS
createContent: function(controller){
this.emailInput = new sap.m.Input('emailInput', {
liveChange: function(event) {
}
})
var passwordInput = new sap.m.Input('passwordInput', {
type: 'Password',
liveChange: function(event) {
}
});
return layout;
},
this is the controller
$.ajax({
type: 'POST',
url: SERVER_URL + '/login',
data : 'j_username=' + myUserName + '&j_password='+ myPassword,
success: function(result) {
...
}
})
this is the servelet
#RestController
#RequestMapping("/login")
#SuppressWarnings("unchecked")
public class AuthenticationController {
#RequestMapping(method = RequestMethod.POST)
#ResponseBody
public String login(#RequestParam(value="j_username", required=true) String email,
#RequestParam(value="j_password", required=true) String password)
{
try {
....do logic and create resultList
return gson.toJson(resultList);
}
catch (Exception e) {
return e.toString();
}
finally {
em.close();
}
}
You can use simple HTML for login page as well. Ultimate aim is to call post service (bydefault /j_spring_security_check) from client page (html or jsp), as long as this is valid, you may call from any extension.
Related
I'm getting this in the console when I'm trying to update data in my database, using spring mvc and ajax from my jsp.
http://localhost:8080/my_project/activerutilisateur/user 405 (Méthode Non Autorisée)
See my code below:
DAO
public Utilisateur updateUtilisateur(Utilisateur utilisateur) {
sessionFactory.getCurrentSession().update(utilisateur);
return utilisateur;
}
Controller
#RequestMapping(value="/activerutilisateur/{username}", method=RequestMethod.PUT, produces = MediaType.APPLICATION_JSON_VALUE, consumes = MediaType.APPLICATION_JSON_VALUE)
#ResponseBody
public Utilisateur activerUtilisateur(#PathVariable String username, #RequestBody Utilisateur utilisateur) {
utilisateur = service.getUtilisateurById(username);
utilisateur.setEnable(true);
return service.updateUtilisateur(utilisateur);
}
Ajax request
<script>
function activerUtilisateur(username) {
var user = {"username" : username}
$.ajax({
contentType: 'application/json',
type: 'POST',
url: 'activerutilisateur/',
data : JSON.stringify(user),
error: function(xhr,error,textStatus){
console.log(textStatus);
},
complete: function(data) {
console.log(data);
console.log('complete done');
},
success: function(data) {
alert('success done');
}
});
}
</script>
It's the only method which doesn't work in the project
Someone could please help me to find what I did wrong?
Thanks
I finally found what's wrong here :
https://matthewbusche.com/blog2/2016/08/06/using-csrf-with-spring-security-and-ajax-calls/
It's due to csrf
Your controller is a POST method, but you are reading the pathVariable, instead of any request body, normally in POST call you need to send Payload to your controller. And in Ajax, you are passing
url: 'activerutilisateur/'+username ----> for PathVariable
data: {'username' : username} ----> There is no requestBody in Controller for this payload.
You should update your controller to have a Request Body as an Argument.
Edited: I ran below code and its working fine in my local machine
JSP/JS Code:
<script>
function activerUtilisateur(username) {
var user = {
"username" : username
}
$.ajax({
contentType: 'application/json',
type: 'POST',
url: 'activerutilisateur/',
data : JSON.stringify(user),
error: function(data){
console.log('Motif erreur : '+data);
},
complete: function(data) {
console.log('complete done');
},
success: function(data) {
console.log('success done');
}
});
}
</script>
Controller Code:
#RequestMapping(value = "/activerutilisateur/", method = RequestMethod.POST)
#ResponseBody
public Utilisateur activerUtilisateur(#RequestBody Utilisateur user) {
service.activerUtilisateur(username);
return user;
}
Model code:
public class Utilisateur {
private String username ;
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
}
Also, it seems you have enabled csrf protection, so check Sending CSRF Token from JS for sending csrf token in the call to the controller.
I suppose that this is your Utilisateur model class :
public class Utilisateur {
private String username ;
// getter & setter
}
In your Controller :
#RequestMapping(value="/activerutilisateur/", method=RequestMethod.POST)
#ResponseBody
public Utilisateur activerUtilisateur(#RequestBody Utilisateur user) {
return service.activerUtilisateur(user.getUsername());
}
In your Ajax Call :
<script type="text/javascript">
function activerUtilisateur(username){
var user = {
"username" : username
}
$.ajax({
type: 'POST',
url: 'activerutilisateur/',
data : JSON.stringify(user)
error: function(xhr, error, textStatus){
console.log('Motif erreur : '+textStatus);
},
success:function(data){
console.log(data);
}
});
}
</script>
View
$("#button").click(function () {
$('#result').html("Processing...");
$.ajax({
url: '#Url.Action("GetData", "Json")',
async: true,
dataType: "json",
type: "GET",
success: function (data) {
$('#result').html(data);
},
});
return false;
});
Controller
public class JsonController : AsyncController
{
[HttpGet]
public async Task<JsonResult> GetData()
{
using (var client = new HttpClient())
{
client.BaseAddress = new Uri("http://localhost:8000/myservice.svc/");
client.DefaultRequestHeaders.Accept.Clear();
client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
HttpResponseMessage response = await client.GetAsync("GetData");
var result = await response.Content.ReadAsAsync<JSONResponse>();
return Json(result, JsonRequestBehavior.AllowGet);
}
}
}
Model
class JSONResponse{
public int Value { get; set; }
public string Text { get; set; }
}
I'm calling an wcf restful service asynchronously from an asp.net mvc application and displaying the result in a div.
When I click the button and the service starts processing and I try to change page meanwhile, I can't... and the page only changes after I get the result from the service.
How can I make it so I can keep changing while the service is executing and when is finished I just display the data in the div?
EDIT: Changing page meaning render different partial views below the div.
As I describe on my blog, async doesn't change the HTTP protocol.
You'll need to use a technology designed for this, such as SignalR.
I am working on SpringMVC, I am passing data from ajax to controller but i got null value in my controller please check my code below
function searchText()
{
var sendData = {
"pName" : "bhanu",
"lName" :"prasad"
}
$.ajax({
type: "POST",
url: "/gDirecotry/ajax/searchUserProfiles.htm,
async: true,
data:sendData,
success :function(result)
{
}
}
MyControllerCode
RequestMapping(value="/gDirecotry/ajax/searchUserProfiles.htm",method=RequestMethod.POST)
public #ResponseBody String getSearchUserProfiles(HttpServletRequest request)
{
String pName = request.getParameter("pName");
//here I got null value
}
any one help me
Hey enjoy the following code.
Javascript AJAX call
function searchText() {
var search = {
"pName" : "bhanu",
"lName" :"prasad"
}
$.ajax({
type: "POST",
contentType : 'application/json; charset=utf-8',
dataType : 'json',
url: "/gDirecotry/ajax/searchUserProfiles.html",
data: JSON.stringify(search), // Note it is important
success :function(result) {
// do what ever you want with data
}
});
}
Spring controller code
RequestMapping(value="/gDirecotry/ajax/searchUserProfiles.htm",method=RequestMethod.POST)
public #ResponseBody String getSearchUserProfiles(#RequestBody Search search, HttpServletRequest request) {
String pName = search.getPName();
String lName = search.getLName();
// your logic next
}
Following Search class will be as follows
class Search {
private String pName;
private String lName;
// getter and setters for above variables
}
Advantage of this class is that, in future you can add more variables to this class if needed.
Eg. if you want to implement sort functionality.
Use this method if you dont want to make a class you can directly send JSON without Stringifying. Use Default Content Type.
Just Use #RequestParam instead of #RequestBody.
#RequestParam Name must be same as in json.
Ajax Call
function searchText() {
var search = {
"pName" : "bhanu",
"lName" :"prasad"
}
$.ajax({
type: "POST",
/*contentType : 'application/json; charset=utf-8',*/ //use Default contentType
dataType : 'json',
url: "/gDirecotry/ajax/searchUserProfiles.htm",
data: search, // Note it is important without stringifying
success :function(result) {
// do what ever you want with data
}
});
Spring Controller
RequestMapping(value="/gDirecotry/ajax/searchUserProfiles.htm",method=RequestMethod.POST)
public #ResponseBody String getSearchUserProfiles(#RequestParam String pName, #RequestParam String lName) {
String pNameParameter = pName;
String lNameParameter = lName;
// your logic next
}
I hope, You need to include the dataType option,
dataType: "JSON"
And you could get the form data in controller as below,
public #ResponseBody String getSearchUserProfiles(#RequestParam("pName") String pName ,HttpServletRequest request)
{
//here I got null value
}
If you can manage to pass your whole json in one query string parameter then you can use rest template on the server side to generate Object from json, but still its not the optimal approach
u take like this
var name=$("name").val();
var email=$("email").val();
var obj = 'name='+name+'&email'+email;
$.ajax({
url:"simple.form",
type:"GET",
data:obj,
contentType:"application/json",
success:function(response){
alert(response);
},
error:function(error){
alert(error);
}
});
spring Controller
#RequestMapping(value = "simple", method = RequestMethod.GET)
public #ResponseBody String emailcheck(#RequestParam("name") String name, #RequestParam("email") String email, HttpSession session) {
String meaaseg = "success";
return meaaseg;
}
I am building a MVC3 web application and I am using knockoutjs. There are two views in the application. SetUpNewCompany and ManageAccount. To Set up a new company the user first enters the account number and clicks search. If the account number already exists the user can click on a button to go to the ManageAccount view. In the SetUpNewCompanyController I redirect using the RedirectToAction method. However, when the Index2 action in ManageAccount is executed the view is not displayed. If I type in the complete URL the view is displayed.
SetUpNewCompanyController.cs
[HttpPost]
public RedirectToRouteResult RedirectToManageAccount(string accountNumber)
{
return RedirectToAction("Index2", new RouteValueDictionary(new {controller=
"ManageAccount", companyId = "7e96b930-a786-44dd-8576-052ce608e38f" }));
}
This above is called by the function below when a button is clicked
self.redirectToManageAccount = function () {
var accountNumber = "7e96b930-a786-44dd-8576-052ce608e38f";
$.ajax({
type: "POST",
url: "/SetUpNewCompany/RedirectToManageAccount",
data: { accountNumber: accountNumber },
success: function (data) {
},
error: function () {
}
});
}
ManageAccountController.cs
public ActionResult Index2(String companyId)
{
var viewModel = new Models.Index();
List<String> compList = new List<String>();
compList.Add("MyCompany");
List<String> usersList = new List<String>();
usersList.Add("User1");
viewModel.Users = usersList;
viewModel.Companies = compList;
viewModel.CompanyId = companyId;
viewModel.Role = "Role1";
return View("ManageAccount",viewModel);
}
The URL that is generated is
http://localhost:53897/ManageAccount/Index2?companyId=7e96b930-a786-44dd-8576-
052ce608e38f
The console window in Firebug shows
GET http://localhost:53897/ManageAccount/Index2?companyId=7e96b930-a786-44dd-8576-
052ce608e38f 200 OK and the spinner keeps spinng
Also, how do I get the URL below instead of the one with querystring
http://localhost:53897/ManageAccount/Index2/7e96b930-a786-44dd-8576-052ce608e38f
Since you use AJAX to call the RedirectToManageAccount action method, you are responsible for handling its response yourself and as your success handler function is empty, you are effectively ignoring whatever arrives as a response.
If you want to force a redirect from within the AJAX response handler, I suggest
Modifying your action method as follows
[HttpPost]
public ActionResult RedirectToManageAccount(string accountNumber)
{
var redirectUrl = new UrlHelper(Request.RequestContext).Action("Index2", "ManageAccount", new { companyId = "7e96b930-a786-44dd-8576-052ce608e38f" });
return Json(new { Url = redirectUrl });
}
Updating your AJAX call in this way
self.redirectToManageAccount = function () {
var accountNumber = "7e96b930-a786-44dd-8576-052ce608e38f";
$.ajax({ type: "POST",
url: "/SetUpNewCompany/RedirectToManageAccount",
data: { accountNumber: accountNumber },
dataType: 'json',
success: function (response) {
window.location.href = response.Url;
},
error: function () {
}
});
}
As for your second question:
Also, how do I get the URL below instead of the one with querystring
http://localhost:53897/ManageAccount/Index2/7e96b930-a786-44dd-8576-052ce608e38f
You just have to define an appropriate route entry for this URL in your RegisterRoutes() function:
routes.MapRoute(null,
"ManageAccount/Index2/{companyId}",
new { controller = "ManageAccount",
action = "Index2" }
);
EDIT: As your AJAX call only serves to call an action method which causes a redirect, you can simplify it in a following way, provided you in this point (on the client side) know the companyId already:
self.redirectToManageAccount = function () {
var companyId = "12345";
window.location.href = '#(Html.ActionUri("Index2", "ManageAccount"))?companyId=' + companyId;
}
where I used this extension method
public static string ActionUri(this HtmlHelper html, string action, string controller)
{
return new UrlHelper(html.ViewContext.RequestContext).Action(action, controller);
}
I have Spring MVC controller:
#Controller
#RequestMapping(value = "/bla")
public class TestController {
#RequestMapping(value = "json", method = RequestMethod.POST)
public #ResponseBody String getJson(#ModelAttribute SearchQueryJson searchQueryJson) {
System.out.println("hih");
System.out.println(searchQueryJson.getQuery());
return new String("{'asd','asdd'}");
}
}
and js:
<script>
$("#searchbox").typeahead({
source: function (typeahead, query) {
return $.post("bla/json", { query: query }, function (data) {
return typeahead.process(data);
});
}
});
</script>
at google chrome debugger i see response {'asd','asdd'}, but nothing happens (dropdown at search box doesn't appears)! i'm using twitter bootstrap typeahead (method 'toLowerCase' of undefined) and https://gist.github.com/2712048
change return typeahead.process(data);
to return typeahead(data);