├── .gitignore
├── .nuget
├── NuGet.Config
└── NuGet.targets
├── MinimalOwinWebApiSelfHost.sln
├── MinimalOwinWebApiSelfHost
├── App.config
├── Controllers
│ └── CompaniesController.cs
├── MinimalOwinWebApiSelfHost.csproj
├── Models
│ ├── ApplicationDbContext.cs
│ ├── AuthModels.cs
│ └── Company.cs
├── OAuthServerProvider
│ └── ApplicationOAuthServerProvider.cs
├── Program.cs
├── Properties
│ └── AssemblyInfo.cs
├── Startup.cs
└── packages.config
└── README.md
/.gitignore:
--------------------------------------------------------------------------------
1 | Thumbs.db
2 | *.obj
3 | *.exe
4 | *.pdb
5 | *.user
6 | *.aps
7 | *.pch
8 | *.vspscc
9 | *_i.c
10 | *_p.c
11 | *.ncb
12 | *.suo
13 | *.sln.docstates
14 | *.tlb
15 | *.tlh
16 | *.bak
17 | *.cache
18 | *.ilk
19 | *.log
20 | [Bb]in
21 | [Dd]ebug*/
22 | *.lib
23 | *.sbr
24 | obj/
25 | [Rr]elease*/
26 | _ReSharper*/
27 | [Tt]est[Rr]esult*
28 | *.vssscc
29 | $tf*/
30 | packages*/
--------------------------------------------------------------------------------
/.nuget/NuGet.Config:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/.nuget/NuGet.targets:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | $(MSBuildProjectDirectory)\..\
5 |
6 |
7 | false
8 |
9 |
10 | false
11 |
12 |
13 | true
14 |
15 |
16 | false
17 |
18 |
19 |
20 |
21 |
22 |
26 |
27 |
28 |
29 |
30 | $([System.IO.Path]::Combine($(SolutionDir), ".nuget"))
31 |
32 |
33 |
34 |
35 | $(SolutionDir).nuget
36 |
37 |
38 |
39 | $(MSBuildProjectDirectory)\packages.$(MSBuildProjectName.Replace(' ', '_')).config
40 | $(MSBuildProjectDirectory)\packages.$(MSBuildProjectName).config
41 |
42 |
43 |
44 | $(MSBuildProjectDirectory)\packages.config
45 | $(PackagesProjectConfig)
46 |
47 |
48 |
49 |
50 | $(NuGetToolsPath)\NuGet.exe
51 | @(PackageSource)
52 |
53 | "$(NuGetExePath)"
54 | mono --runtime=v4.0.30319 "$(NuGetExePath)"
55 |
56 | $(TargetDir.Trim('\\'))
57 |
58 | -RequireConsent
59 | -NonInteractive
60 |
61 | "$(SolutionDir) "
62 | "$(SolutionDir)"
63 |
64 |
65 | $(NuGetCommand) install "$(PackagesConfig)" -source "$(PackageSources)" $(NonInteractiveSwitch) $(RequireConsentSwitch) -solutionDir $(PaddedSolutionDir)
66 | $(NuGetCommand) pack "$(ProjectPath)" -Properties "Configuration=$(Configuration);Platform=$(Platform)" $(NonInteractiveSwitch) -OutputDirectory "$(PackageOutputDir)" -symbols
67 |
68 |
69 |
70 | RestorePackages;
71 | $(BuildDependsOn);
72 |
73 |
74 |
75 |
76 | $(BuildDependsOn);
77 | BuildPackage;
78 |
79 |
80 |
81 |
82 |
83 |
84 |
89 |
90 |
91 |
92 |
93 |
94 |
95 |
96 |
97 |
99 |
100 |
103 |
104 |
105 |
106 |
108 |
109 |
112 |
113 |
114 |
115 |
116 |
117 |
118 |
119 |
120 |
121 |
122 |
123 |
124 |
125 |
126 |
141 |
142 |
143 |
144 |
145 |
--------------------------------------------------------------------------------
/MinimalOwinWebApiSelfHost.sln:
--------------------------------------------------------------------------------
1 |
2 | Microsoft Visual Studio Solution File, Format Version 12.00
3 | # Visual Studio 2013
4 | VisualStudioVersion = 12.0.30723.0
5 | MinimumVisualStudioVersion = 10.0.40219.1
6 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MinimalOwinWebApiSelfHost", "MinimalOwinWebApiSelfHost\MinimalOwinWebApiSelfHost.csproj", "{8CB280DB-41B5-4786-AEFB-1308A1859493}"
7 | EndProject
8 | Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = ".nuget", ".nuget", "{AC43AE7A-9ACE-4C19-B96F-E62266AD519B}"
9 | ProjectSection(SolutionItems) = preProject
10 | .nuget\NuGet.Config = .nuget\NuGet.Config
11 | .nuget\NuGet.exe = .nuget\NuGet.exe
12 | .nuget\NuGet.targets = .nuget\NuGet.targets
13 | EndProjectSection
14 | EndProject
15 | Global
16 | GlobalSection(SolutionConfigurationPlatforms) = preSolution
17 | Debug|Any CPU = Debug|Any CPU
18 | Release|Any CPU = Release|Any CPU
19 | EndGlobalSection
20 | GlobalSection(ProjectConfigurationPlatforms) = postSolution
21 | {8CB280DB-41B5-4786-AEFB-1308A1859493}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
22 | {8CB280DB-41B5-4786-AEFB-1308A1859493}.Debug|Any CPU.Build.0 = Debug|Any CPU
23 | {8CB280DB-41B5-4786-AEFB-1308A1859493}.Release|Any CPU.ActiveCfg = Release|Any CPU
24 | {8CB280DB-41B5-4786-AEFB-1308A1859493}.Release|Any CPU.Build.0 = Release|Any CPU
25 | EndGlobalSection
26 | GlobalSection(SolutionProperties) = preSolution
27 | HideSolutionNode = FALSE
28 | EndGlobalSection
29 | EndGlobal
30 |
--------------------------------------------------------------------------------
/MinimalOwinWebApiSelfHost/App.config:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
--------------------------------------------------------------------------------
/MinimalOwinWebApiSelfHost/Controllers/CompaniesController.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Text;
5 | using System.Threading.Tasks;
6 | using System.Web.Http;
7 | using System.Net.Http;
8 | using MinimalOwinWebApiSelfHost.Models;
9 |
10 | // Add these usings:
11 | using System.Data.Entity;
12 |
13 | namespace MinimalOwinWebApiSelfHost.Controllers
14 | {
15 | [Authorize(Roles="Admin")]
16 | public class CompaniesController : ApiController
17 | {
18 | ApplicationDbContext dbContext = new ApplicationDbContext();
19 |
20 | public IEnumerable Get()
21 | {
22 | return dbContext.Companies;
23 | }
24 |
25 |
26 | public async Task Get(int id)
27 | {
28 | var company = await dbContext.Companies.FirstOrDefaultAsync(c => c.Id == id);
29 | if (company == null)
30 | {
31 | throw new HttpResponseException(
32 | System.Net.HttpStatusCode.NotFound);
33 | }
34 | return company;
35 | }
36 |
37 |
38 | public async Task Post(Company company)
39 | {
40 | if (company == null)
41 | {
42 | return BadRequest("Argument Null");
43 | }
44 | var companyExists = await dbContext.Companies.AnyAsync(c => c.Id == company.Id);
45 |
46 | if (companyExists)
47 | {
48 | return BadRequest("Exists");
49 | }
50 |
51 | dbContext.Companies.Add(company);
52 | await dbContext.SaveChangesAsync();
53 | return Ok();
54 | }
55 |
56 |
57 | public async Task Put(Company company)
58 | {
59 | if (company == null)
60 | {
61 | return BadRequest("Argument Null");
62 | }
63 | var existing = await dbContext.Companies.FirstOrDefaultAsync(c => c.Id == company.Id);
64 |
65 | if (existing == null)
66 | {
67 | return NotFound();
68 | }
69 |
70 | existing.Name = company.Name;
71 | await dbContext.SaveChangesAsync();
72 | return Ok();
73 | }
74 |
75 |
76 | public async Task Delete(int id)
77 | {
78 | var company = await dbContext.Companies.FirstOrDefaultAsync(c => c.Id == id);
79 | if (company == null)
80 | {
81 | return NotFound();
82 | }
83 | dbContext.Companies.Remove(company);
84 | await dbContext.SaveChangesAsync();
85 | return Ok();
86 | }
87 | }
88 | }
89 |
--------------------------------------------------------------------------------
/MinimalOwinWebApiSelfHost/MinimalOwinWebApiSelfHost.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Debug
6 | AnyCPU
7 | {8CB280DB-41B5-4786-AEFB-1308A1859493}
8 | Exe
9 | Properties
10 | MinimalOwinWebApiSelfHost
11 | MinimalOwinWebApiSelfHost
12 | v4.5
13 | 512
14 | ..\
15 | true
16 |
17 |
18 | AnyCPU
19 | true
20 | full
21 | false
22 | bin\Debug\
23 | DEBUG;TRACE
24 | prompt
25 | 4
26 |
27 |
28 | AnyCPU
29 | pdbonly
30 | true
31 | bin\Release\
32 | TRACE
33 | prompt
34 | 4
35 |
36 |
37 |
38 | ..\packages\EntityFramework.6.1.2\lib\net45\EntityFramework.dll
39 |
40 |
41 | ..\packages\EntityFramework.6.1.2\lib\net45\EntityFramework.SqlServer.dll
42 |
43 |
44 | ..\packages\EntityFramework.SqlServerCompact.6.1.2\lib\net45\EntityFramework.SqlServerCompact.dll
45 |
46 |
47 | ..\packages\Microsoft.AspNet.Identity.Core.2.2.0-alpha1\lib\net45\Microsoft.AspNet.Identity.Core.dll
48 |
49 |
50 | ..\packages\Microsoft.AspNet.Identity.EntityFramework.2.1.0\lib\net45\Microsoft.AspNet.Identity.EntityFramework.dll
51 |
52 |
53 | ..\packages\Microsoft.AspNet.Identity.Owin.2.2.0-alpha1\lib\net45\Microsoft.AspNet.Identity.Owin.dll
54 |
55 |
56 | False
57 | ..\packages\Microsoft.Owin.2.1.0\lib\net45\Microsoft.Owin.dll
58 |
59 |
60 | ..\packages\Microsoft.Owin.Host.HttpListener.2.0.2\lib\net45\Microsoft.Owin.Host.HttpListener.dll
61 |
62 |
63 | ..\packages\Microsoft.Owin.Hosting.2.0.2\lib\net45\Microsoft.Owin.Hosting.dll
64 |
65 |
66 | ..\packages\Microsoft.Owin.Security.2.1.0\lib\net45\Microsoft.Owin.Security.dll
67 |
68 |
69 | ..\packages\Microsoft.Owin.Security.Cookies.2.1.0\lib\net45\Microsoft.Owin.Security.Cookies.dll
70 |
71 |
72 | ..\packages\Microsoft.Owin.Security.OAuth.2.1.0\lib\net45\Microsoft.Owin.Security.OAuth.dll
73 |
74 |
75 | ..\packages\Newtonsoft.Json.6.0.4\lib\net45\Newtonsoft.Json.dll
76 |
77 |
78 | ..\packages\Owin.1.0\lib\net40\Owin.dll
79 |
80 |
81 |
82 |
83 |
84 | True
85 | ..\packages\Microsoft.SqlServer.Compact.4.0.8876.1\lib\net40\System.Data.SqlServerCe.dll
86 |
87 |
88 |
89 | False
90 | ..\packages\Microsoft.AspNet.WebApi.Client.5.2.3-beta1\lib\net45\System.Net.Http.Formatting.dll
91 |
92 |
93 | False
94 | ..\packages\Microsoft.AspNet.WebApi.Core.5.2.3-beta1\lib\net45\System.Web.Http.dll
95 |
96 |
97 | ..\packages\Microsoft.AspNet.WebApi.Owin.5.2.3-beta1\lib\net45\System.Web.Http.Owin.dll
98 |
99 |
100 |
101 |
102 |
103 |
104 |
105 |
106 |
107 |
108 |
109 |
110 |
111 |
112 |
113 |
114 |
115 |
116 |
117 | Designer
118 |
119 |
120 |
121 |
122 |
123 |
124 |
125 |
126 | This project references NuGet package(s) that are missing on this computer. Enable NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}.
127 |
128 |
129 |
130 |
131 |
132 | if not exist "$(TargetDir)x86" md "$(TargetDir)x86"
133 | xcopy /s /y "$(SolutionDir)packages\Microsoft.SqlServer.Compact.4.0.8876.1\NativeBinaries\x86\*.*" "$(TargetDir)x86"
134 | if not exist "$(TargetDir)amd64" md "$(TargetDir)amd64"
135 | xcopy /s /y "$(SolutionDir)packages\Microsoft.SqlServer.Compact.4.0.8876.1\NativeBinaries\amd64\*.*" "$(TargetDir)amd64"
136 |
137 |
144 |
--------------------------------------------------------------------------------
/MinimalOwinWebApiSelfHost/Models/ApplicationDbContext.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Text;
5 | using System.Threading.Tasks;
6 |
7 | // Add using:
8 | using System.Data.Entity;
9 | using System.Security.Claims;
10 |
11 | namespace MinimalOwinWebApiSelfHost.Models
12 | {
13 | public class ApplicationDbContext : DbContext
14 | {
15 | public ApplicationDbContext()
16 | : base("MyDatabase")
17 | {
18 |
19 | }
20 |
21 | static ApplicationDbContext()
22 | {
23 | Database.SetInitializer(new ApplicationDbInitializer());
24 | }
25 |
26 | public IDbSet Companies { get; set; }
27 | public IDbSet Users { get; set; }
28 | public IDbSet Claims { get; set; }
29 | }
30 |
31 |
32 | public class ApplicationDbInitializer
33 | : DropCreateDatabaseAlways
34 | {
35 | protected async override void Seed(ApplicationDbContext context)
36 | {
37 | context.Companies.Add(new Company { Name = "Microsoft" });
38 | context.Companies.Add(new Company { Name = "Apple" });
39 | context.Companies.Add(new Company { Name = "Google" });
40 | context.SaveChanges();
41 |
42 | // Set up two initial users with different role claims:
43 | var john = new MyUser { Email = "john@example.com" };
44 | var jimi = new MyUser { Email = "jimi@Example.com" };
45 |
46 | john.Claims.Add(new MyUserClaim { ClaimType = ClaimTypes.Name, UserId = john.Id, ClaimValue = john.Email });
47 | john.Claims.Add(new MyUserClaim { ClaimType = ClaimTypes.Role, UserId = john.Id, ClaimValue = "Admin" });
48 |
49 | jimi.Claims.Add(new MyUserClaim { ClaimType = ClaimTypes.Name, UserId = jimi.Id, ClaimValue = jimi.Email });
50 | jimi.Claims.Add(new MyUserClaim { ClaimType = ClaimTypes.Role, UserId = john.Id, ClaimValue = "User" });
51 |
52 | var store = new MyUserStore(context);
53 | await store.AddUserAsync(john, "JohnsPassword");
54 | await store.AddUserAsync(jimi, "JimisPassword");
55 | }
56 | }
57 | }
58 |
--------------------------------------------------------------------------------
/MinimalOwinWebApiSelfHost/Models/AuthModels.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Text;
5 | using System.Threading.Tasks;
6 |
7 | // Add usings:
8 | using System.Data.Entity;
9 | using System.ComponentModel.DataAnnotations;
10 | using System.Security.Claims;
11 |
12 | namespace MinimalOwinWebApiSelfHost.Models
13 | {
14 | public class MyUser
15 | {
16 | public MyUser()
17 | {
18 | Id = Guid.NewGuid().ToString();
19 | Claims = new List();
20 | }
21 |
22 | [Key]
23 | public string Id { get; set; }
24 | public string Email { get; set; }
25 | public string PasswordHash { get; set; }
26 | public ICollection Claims { get; set; }
27 | }
28 |
29 |
30 | public class MyUserClaim
31 | {
32 | public MyUserClaim()
33 | {
34 | Id = Guid.NewGuid().ToString();
35 | }
36 | [Key]
37 | public string Id { get; set; }
38 | public string UserId { get; set; }
39 | public string ClaimType { get; set; }
40 | public string ClaimValue { get; set; }
41 | }
42 |
43 |
44 | public class MyPasswordHasher
45 | {
46 | public string CreateHash(string password)
47 | {
48 | // FOR DEMO ONLY! Use a standard method or
49 | // crypto library to do this for real:
50 | char[] chars = password.ToArray();
51 | char[] hash = chars.Reverse().ToArray();
52 | return new string(hash);
53 | }
54 | }
55 |
56 |
57 | public class MyUserStore
58 | {
59 | ApplicationDbContext _db;
60 | public MyUserStore(ApplicationDbContext context)
61 | {
62 | _db = context;
63 | }
64 |
65 |
66 | public async Task AddUserAsync(MyUser user, string password)
67 | {
68 | if (await UserExists(user))
69 | {
70 | throw new Exception(
71 | "A user with that Email address already exists");
72 | }
73 | var hasher = new MyPasswordHasher();
74 | user.PasswordHash = hasher.CreateHash(password).ToString();
75 | _db.Users.Add(user);
76 | await _db.SaveChangesAsync();
77 | }
78 |
79 |
80 | public async Task FindByEmailAsync(string email)
81 | {
82 | var user = _db.Users
83 | .Include(c => c.Claims)
84 | .FirstOrDefaultAsync(u => u.Email == email);
85 |
86 | return await _db.Users
87 | .FirstOrDefaultAsync(u => u.Email == email);
88 | }
89 |
90 |
91 | public async Task FindByIdAsync(string userId)
92 | {
93 | return await _db.Users
94 | .FirstOrDefaultAsync(u => u.Id == userId);
95 | }
96 |
97 |
98 | public async Task UserExists(MyUser user)
99 | {
100 | return await _db.Users
101 | .AnyAsync(u => u.Id == user.Id || u.Email == user.Email);
102 | }
103 |
104 |
105 | public async Task AddClaimAsync(string UserId, MyUserClaim claim)
106 | {
107 | var user = await FindByIdAsync(UserId);
108 | if(user == null)
109 | {
110 | throw new Exception("User does not exist");
111 | }
112 | user.Claims.Add(claim);
113 | await _db.SaveChangesAsync();
114 | }
115 |
116 |
117 | public bool PasswordIsValid(MyUser user, string password)
118 | {
119 | var hasher = new MyPasswordHasher();
120 | var hash = hasher.CreateHash(password);
121 | return hash.Equals(user.PasswordHash);
122 | }
123 | }
124 |
125 |
126 | //public class Role
127 | //{
128 | // public Role()
129 | // {
130 | // Id = Guid.NewGuid().ToString();
131 | // }
132 |
133 | // [Key]
134 | // public string Id { get; set; }
135 | // public string Name { get; set; }
136 | // public List Users { get; set; }
137 | //}
138 |
139 |
140 | //public class UserRole
141 | //{
142 | // public string UserId { get; set; }
143 | // public User User { get; set; }
144 |
145 | // public string RoleId { get; set; }
146 | // public Role Role { get; set; }
147 | //}
148 |
149 |
150 | //public class UserManager
151 | //{
152 | // UserStore _userStore;
153 | // public UserManager(UserStore userStore)
154 | // {
155 | // _userStore = userStore;
156 | // }
157 |
158 |
159 | // public async Task CreateAsync(User user, string password)
160 | // {
161 | // if(await _userStore.UserExists(user))
162 | // {
163 | // throw new Exception("A user with that Email address already exists");
164 | // }
165 | // var hasher = new PasswordHasher();
166 | // user.PasswordHash = hasher.CreateHash(password);
167 | // await _userStore.AddUserAsync(user);
168 | // }
169 |
170 |
171 | // public async Task AddClaim(string UserId, Claim claim)
172 | // {
173 | // _userStore.AddClaim()
174 | // }
175 | //}
176 | }
177 |
--------------------------------------------------------------------------------
/MinimalOwinWebApiSelfHost/Models/Company.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Text;
5 | using System.Threading.Tasks;
6 |
7 | // Add using:
8 | using System.ComponentModel.DataAnnotations;
9 |
10 | namespace MinimalOwinWebApiSelfHost.Models
11 | {
12 | public class Company
13 | {
14 | // Add Key Attribute:
15 | [Key]
16 | public int Id { get; set; }
17 | public string Name { get; set; }
18 | }
19 | }
20 |
--------------------------------------------------------------------------------
/MinimalOwinWebApiSelfHost/OAuthServerProvider/ApplicationOAuthServerProvider.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Text;
5 | using System.Threading.Tasks;
6 |
7 | // Add Usings:
8 | using Microsoft.Owin.Security;
9 | using Microsoft.Owin.Security.OAuth;
10 | using System.Security.Claims;
11 | using MinimalOwinWebApiSelfHost.Models;
12 |
13 |
14 | namespace MinimalOwinWebApiSelfHost.OAuthServerProvider
15 | {
16 | public class ApplicationOAuthServerProvider
17 | : OAuthAuthorizationServerProvider
18 | {
19 | public override async Task ValidateClientAuthentication(
20 | OAuthValidateClientAuthenticationContext context)
21 | {
22 | // This call is required...
23 | // but we're not using client authentication, so validate and move on...
24 | await Task.FromResult(context.Validated());
25 | }
26 |
27 |
28 | public override async Task GrantResourceOwnerCredentials(
29 | OAuthGrantResourceOwnerCredentialsContext context)
30 | {
31 | // Retrieve user from database:
32 | var store = new MyUserStore(new ApplicationDbContext());
33 | var user = await store.FindByEmailAsync(context.UserName);
34 |
35 | // Validate user/password:
36 | if(user == null || !store.PasswordIsValid(user, context.Password))
37 | {
38 | context.SetError(
39 | "invalid_grant", "The user name or password is incorrect.");
40 | context.Rejected();
41 | return;
42 | }
43 |
44 | // Add claims associated with this user to the ClaimsIdentity object:
45 | var identity = new ClaimsIdentity(context.Options.AuthenticationType);
46 | foreach(var userClaim in user.Claims)
47 | {
48 | identity.AddClaim(new Claim(userClaim.ClaimType, userClaim.ClaimValue));
49 | }
50 |
51 | context.Validated(identity);
52 | }
53 | }
54 | }
55 |
--------------------------------------------------------------------------------
/MinimalOwinWebApiSelfHost/Program.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Text;
5 | using System.Threading.Tasks;
6 |
7 | // Add reference to:
8 | using Microsoft.Owin.Hosting;
9 | using System.Data.Entity;
10 | using MinimalOwinWebApiSelfHost.Models;
11 |
12 | namespace MinimalOwinWebApiSelfHost
13 | {
14 | class Program
15 | {
16 | static void Main(string[] args)
17 | {
18 | // Specify the URI to use for the local host:
19 | string baseUri = "http://localhost:8080";
20 |
21 | Console.WriteLine("Starting web Server...");
22 | WebApp.Start(baseUri);
23 | Console.WriteLine("Server running at {0} - press Enter to quit. ", baseUri);
24 | Console.ReadLine();
25 | }
26 | }
27 | }
28 |
--------------------------------------------------------------------------------
/MinimalOwinWebApiSelfHost/Properties/AssemblyInfo.cs:
--------------------------------------------------------------------------------
1 | using System.Reflection;
2 | using System.Runtime.CompilerServices;
3 | using System.Runtime.InteropServices;
4 |
5 | // General Information about an assembly is controlled through the following
6 | // set of attributes. Change these attribute values to modify the information
7 | // associated with an assembly.
8 | [assembly: AssemblyTitle("MinimalOwinWebApiSelfHost")]
9 | [assembly: AssemblyDescription("")]
10 | [assembly: AssemblyConfiguration("")]
11 | [assembly: AssemblyCompany("")]
12 | [assembly: AssemblyProduct("MinimalOwinWebApiSelfHost")]
13 | [assembly: AssemblyCopyright("Copyright © 2015")]
14 | [assembly: AssemblyTrademark("")]
15 | [assembly: AssemblyCulture("")]
16 |
17 | // Setting ComVisible to false makes the types in this assembly not visible
18 | // to COM components. If you need to access a type in this assembly from
19 | // COM, set the ComVisible attribute to true on that type.
20 | [assembly: ComVisible(false)]
21 |
22 | // The following GUID is for the ID of the typelib if this project is exposed to COM
23 | [assembly: Guid("4e5dbf68-a38f-4291-a066-7e6c73c35b7f")]
24 |
25 | // Version information for an assembly consists of the following four values:
26 | //
27 | // Major Version
28 | // Minor Version
29 | // Build Number
30 | // Revision
31 | //
32 | // You can specify all the values or you can default the Build and Revision Numbers
33 | // by using the '*' as shown below:
34 | // [assembly: AssemblyVersion("1.0.*")]
35 | [assembly: AssemblyVersion("1.0.0.0")]
36 | [assembly: AssemblyFileVersion("1.0.0.0")]
37 |
--------------------------------------------------------------------------------
/MinimalOwinWebApiSelfHost/Startup.cs:
--------------------------------------------------------------------------------
1 | using System;
2 |
3 | // Add the following usings:
4 | using Owin;
5 | using System.Web.Http;
6 | using MinimalOwinWebApiSelfHost.Models;
7 | using MinimalOwinWebApiSelfHost.OAuthServerProvider;
8 | using Microsoft.Owin.Security.OAuth;
9 | using Microsoft.Owin;
10 |
11 |
12 | namespace MinimalOwinWebApiSelfHost
13 | {
14 | public class Startup
15 | {
16 | // This method is required by Katana:
17 | public void Configuration(IAppBuilder app)
18 | {
19 | ConfigureAuth(app);
20 |
21 | var webApiConfiguration = ConfigureWebApi();
22 | app.UseWebApi(webApiConfiguration);
23 | }
24 |
25 |
26 | private void ConfigureAuth(IAppBuilder app)
27 | {
28 | var OAuthOptions = new OAuthAuthorizationServerOptions
29 | {
30 | TokenEndpointPath = new PathString("/Token"),
31 | Provider = new ApplicationOAuthServerProvider(),
32 | AccessTokenExpireTimeSpan = TimeSpan.FromDays(14),
33 |
34 | // Only do this for demo!!
35 | AllowInsecureHttp = true
36 | };
37 | app.UseOAuthAuthorizationServer(OAuthOptions);
38 | app.UseOAuthBearerAuthentication(new OAuthBearerAuthenticationOptions());
39 | }
40 |
41 |
42 | private HttpConfiguration ConfigureWebApi()
43 | {
44 | var config = new HttpConfiguration();
45 | config.Routes.MapHttpRoute(
46 | "DefaultApi",
47 | "api/{controller}/{id}",
48 | new { id = RouteParameter.Optional });
49 | return config;
50 | }
51 | }
52 | }
53 |
--------------------------------------------------------------------------------
/MinimalOwinWebApiSelfHost/packages.config:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # MinimalOwinWebApiSelfHost
2 |
3 | This repo contains source code for a series of articles. Each article builds upon the work done in the last. In order that the source for each article make sense in the context of the article, I have separated branches relevant to each article.
4 |
5 | * **Branch: Master -** Will always contain all of the changes, and be up to date with the most recent article in the series
6 |
7 | The branches below are both referred to in [ASP.NET Web Api 2.2: Create a Self-Hosted OWIN-Based Web Api from Scratch](http://typecastexception.com/post/2015/01/11/ASPNET-Web-Api-22-Create-a-Self-Hosted-OWIN-Based-Web-Api-from-Scratch.aspx)
8 |
9 | * **Branch: api -** The minimal example implementation of a self-hosted Web Api application using OWIN/Katana
10 | * **Branch: ef -** Extends the example above by adding entity framework and a local, file-based database (SQL CE)
11 |
12 | The next branch, `auth-minimal` is referred to in the post [ASP.NET Web Api: Understanding OWIN/Katana Authentication/Authorization Part I: Concepts](http://typecastexception.com/post/2015/01/19/ASPNET-Web-Api-Understanding-OWINKatana-AuthenticationAuthorization-Part-I-Concepts.aspx)
13 |
14 | * **Branch: auth-minimal -** Adds simplified authentication examples to the previous branches. Identity is not used, and database persistence is not yet implemented for the auth stuff.
15 |
16 | The next branch, auth-db is referred to in the post [ASP.NET Web Api: Understanding OWIN/Katana Authentication/Authorization Part II: Models and Persistence](http://typecastexception.com/post/2015/01/25/ASPNET-Web-Api-Understanding-OWINKatana-AuthenticationAuthorization-Part-II-Models-and-Persistence.aspx)
17 |
18 | * **Branch: auth-db -** Adds entity models and database persistence.
19 | *
20 |
21 | The Final Branch, `auth-identity` is referred to in the post [ASP.NET Web API: Understanding OWIN/Katana Authentication/Authorization Part III: Adding Identity](http://typecastexception.com/post/2015/02/15/ASPNET-Web-API-Understanding-OWINKatana-AuthenticationAuthorization-Part-III-Adding-Identity.aspx)
22 |
23 | * **Branch: auth-identity ** Replace bare-bones roll-our-own implementation with a minimal Identity framework implementation.
24 |
25 |
26 |
--------------------------------------------------------------------------------